• 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(PERFETTO_IMPLEMENTATION)
19 #define PERFETTO_IMPLEMENTATION
20 #endif
21 #if !defined(GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER)
22 #define GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
23 #endif
24 #if !defined(GOOGLE_PROTOBUF_NO_RTTI)
25 #define GOOGLE_PROTOBUF_NO_RTTI
26 #endif
27 #include "perfetto.h"
28 // gen_amalgamated begin source: src/base/ctrl_c_handler.cc
29 // gen_amalgamated begin header: include/perfetto/ext/base/ctrl_c_handler.h
30 /*
31  * Copyright (C) 2021 The Android Open Source Project
32  *
33  * Licensed under the Apache License, Version 2.0 (the "License");
34  * you may not use this file except in compliance with the License.
35  * You may obtain a copy of the License at
36  *
37  *      http://www.apache.org/licenses/LICENSE-2.0
38  *
39  * Unless required by applicable law or agreed to in writing, software
40  * distributed under the License is distributed on an "AS IS" BASIS,
41  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
42  * See the License for the specific language governing permissions and
43  * limitations under the License.
44  */
45 
46 #ifndef INCLUDE_PERFETTO_EXT_BASE_CTRL_C_HANDLER_H_
47 #define INCLUDE_PERFETTO_EXT_BASE_CTRL_C_HANDLER_H_
48 
49 namespace perfetto {
50 namespace base {
51 
52 // On Linux/Android/Mac: installs SIGINT + SIGTERM signal handlers.
53 // On Windows: installs a SetConsoleCtrlHandler() handler.
54 // The passed handler must be async safe.
55 using CtrlCHandlerFunction = void (*)();
56 void InstallCtrCHandler(CtrlCHandlerFunction);
57 
58 }  // namespace base
59 }  // namespace perfetto
60 
61 #endif  // INCLUDE_PERFETTO_EXT_BASE_CTRL_C_HANDLER_H_
62 /*
63  * Copyright (C) 2021 The Android Open Source Project
64  *
65  * Licensed under the Apache License, Version 2.0 (the "License");
66  * you may not use this file except in compliance with the License.
67  * You may obtain a copy of the License at
68  *
69  *      http://www.apache.org/licenses/LICENSE-2.0
70  *
71  * Unless required by applicable law or agreed to in writing, software
72  * distributed under the License is distributed on an "AS IS" BASIS,
73  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
74  * See the License for the specific language governing permissions and
75  * limitations under the License.
76  */
77 
78 // gen_amalgamated expanded: #include "perfetto/ext/base/ctrl_c_handler.h"
79 
80 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
81 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
82 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
83 
84 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
85 #include <Windows.h>
86 #include <io.h>
87 #else
88 #include <signal.h>
89 #include <unistd.h>
90 #endif
91 
92 namespace perfetto {
93 namespace base {
94 
95 namespace {
96 CtrlCHandlerFunction g_handler = nullptr;
97 }
98 
InstallCtrCHandler(CtrlCHandlerFunction handler)99 void InstallCtrCHandler(CtrlCHandlerFunction handler) {
100   PERFETTO_CHECK(g_handler == nullptr);
101   g_handler = handler;
102 
103 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
104   auto trampoline = [](DWORD type) -> int {
105     if (type == CTRL_C_EVENT) {
106       g_handler();
107       return true;
108     }
109     return false;
110   };
111   ::SetConsoleCtrlHandler(trampoline, true);
112 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
113     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
114     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
115   // Setup signal handler.
116   struct sigaction sa {};
117 
118 // Glibc headers for sa_sigaction trigger this.
119 #pragma GCC diagnostic push
120 #if defined(__clang__)
121 #pragma GCC diagnostic ignored "-Wdisabled-macro-expansion"
122 #endif
123   sa.sa_handler = [](int) { g_handler(); };
124   sa.sa_flags = static_cast<decltype(sa.sa_flags)>(SA_RESETHAND | SA_RESTART);
125 #pragma GCC diagnostic pop
126   sigaction(SIGINT, &sa, nullptr);
127   sigaction(SIGTERM, &sa, nullptr);
128 #else
129   // Do nothing on NaCL and Fuchsia.
130   ignore_result(handler);
131 #endif
132 }
133 
134 }  // namespace base
135 }  // namespace perfetto
136 // gen_amalgamated begin source: src/base/event_fd.cc
137 // gen_amalgamated begin header: include/perfetto/ext/base/event_fd.h
138 // gen_amalgamated begin header: include/perfetto/base/platform_handle.h
139 /*
140  * Copyright (C) 2020 The Android Open Source Project
141  *
142  * Licensed under the Apache License, Version 2.0 (the "License");
143  * you may not use this file except in compliance with the License.
144  * You may obtain a copy of the License at
145  *
146  *      http://www.apache.org/licenses/LICENSE-2.0
147  *
148  * Unless required by applicable law or agreed to in writing, software
149  * distributed under the License is distributed on an "AS IS" BASIS,
150  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
151  * See the License for the specific language governing permissions and
152  * limitations under the License.
153  */
154 
155 #ifndef INCLUDE_PERFETTO_BASE_PLATFORM_HANDLE_H_
156 #define INCLUDE_PERFETTO_BASE_PLATFORM_HANDLE_H_
157 
158 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
159 
160 namespace perfetto {
161 namespace base {
162 
163 // PlatformHandle should be used only for types that are HANDLE(s) in Windows.
164 // It should NOT be used to blanket-replace "int fd" in the codebase.
165 // Windows has two types of "handles", which, in UNIX-land, both map to int:
166 // 1. File handles returned by the posix-compatibility API like _open().
167 //    These are just int(s) and should stay such, because all the posix-like API
168 //    in Windows.h take an int, not a HANDLE.
169 // 2. Handles returned by old-school WINAPI like CreateFile, CreateEvent etc.
170 //    These are proper HANDLE(s). PlatformHandle should be used here.
171 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
172 // Windows.h typedefs HANDLE to void*. We use void* here to avoid leaking
173 // Windows.h through our headers.
174 using PlatformHandle = void*;
175 
176 // On Windows both nullptr and 0xffff... (INVALID_HANDLE_VALUE) are invalid.
177 struct PlatformHandleChecker {
IsValidperfetto::base::PlatformHandleChecker178   static inline bool IsValid(PlatformHandle h) {
179     return h && h != reinterpret_cast<PlatformHandle>(-1);
180   }
181 };
182 #else
183 using PlatformHandle = int;
184 struct PlatformHandleChecker {
185   static inline bool IsValid(PlatformHandle h) { return h >= 0; }
186 };
187 #endif
188 
189 // The definition of this lives in base/file_utils.cc (to avoid creating an
190 // extra build edge for a one liner). This is really an alias for close() (UNIX)
191 // CloseHandle() (Windows). THe indirection layer is just to avoid leaking
192 // system headers like Windows.h through perfetto headers.
193 // Thre return value is always UNIX-style: 0 on success, -1 on failure.
194 int ClosePlatformHandle(PlatformHandle);
195 
196 }  // namespace base
197 }  // namespace perfetto
198 
199 #endif  // INCLUDE_PERFETTO_BASE_PLATFORM_HANDLE_H_
200 // gen_amalgamated begin header: include/perfetto/ext/base/scoped_file.h
201 /*
202  * Copyright (C) 2017 The Android Open Source Project
203  *
204  * Licensed under the Apache License, Version 2.0 (the "License");
205  * you may not use this file except in compliance with the License.
206  * You may obtain a copy of the License at
207  *
208  *      http://www.apache.org/licenses/LICENSE-2.0
209  *
210  * Unless required by applicable law or agreed to in writing, software
211  * distributed under the License is distributed on an "AS IS" BASIS,
212  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
213  * See the License for the specific language governing permissions and
214  * limitations under the License.
215  */
216 
217 #ifndef INCLUDE_PERFETTO_EXT_BASE_SCOPED_FILE_H_
218 #define INCLUDE_PERFETTO_EXT_BASE_SCOPED_FILE_H_
219 
220 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
221 
222 #include <stdio.h>
223 
224 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
225 #include <dirent.h>  // For DIR* / opendir().
226 #endif
227 
228 #include <string>
229 
230 // gen_amalgamated expanded: #include "perfetto/base/export.h"
231 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
232 // gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
233 
234 namespace perfetto {
235 namespace base {
236 
237 namespace internal {
238 // Used for the most common cases of ScopedResource where there is only one
239 // invalid value.
240 template <typename T, T InvalidValue>
241 struct DefaultValidityChecker {
IsValidperfetto::base::internal::DefaultValidityChecker242   static bool IsValid(T t) { return t != InvalidValue; }
243 };
244 }  // namespace internal
245 
246 // RAII classes for auto-releasing fds and dirs.
247 // if T is a pointer type, InvalidValue must be nullptr. Doing otherwise
248 // causes weird unexpected behaviors (See https://godbolt.org/z/5nGMW4).
249 template <typename T,
250           int (*CloseFunction)(T),
251           T InvalidValue,
252           bool CheckClose = true,
253           class Checker = internal::DefaultValidityChecker<T, InvalidValue>>
254 class PERFETTO_EXPORT ScopedResource {
255  public:
256   using ValidityChecker = Checker;
257   static constexpr T kInvalid = InvalidValue;
258 
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 Checker::IsValid(t_); }
reset(T r=InvalidValue)272   void reset(T r = InvalidValue) {
273     if (Checker::IsValid(t_)) {
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   T t_;
291 };
292 
293 // Declared in file_utils.h. Forward declared to avoid #include cycles.
294 int PERFETTO_EXPORT CloseFile(int fd);
295 
296 // Use this for file resources obtained via open() and similar APIs.
297 using ScopedFile = ScopedResource<int, CloseFile, -1>;
298 using ScopedFstream = ScopedResource<FILE*, fclose, nullptr>;
299 
300 // Use this for resources that are HANDLE on Windows. See comments in
301 // platform_handle.h
302 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
303 using ScopedPlatformHandle = ScopedResource<PlatformHandle,
304                                             ClosePlatformHandle,
305                                             /*InvalidValue=*/nullptr,
306                                             /*CheckClose=*/true,
307                                             PlatformHandleChecker>;
308 #else
309 // On non-windows systems we alias ScopedPlatformHandle to ScopedFile because
310 // they are really the same. This is to allow assignments between the two in
311 // Linux-specific code paths that predate ScopedPlatformHandle.
312 static_assert(std::is_same<int, PlatformHandle>::value, "");
313 using ScopedPlatformHandle = ScopedFile;
314 
315 // DIR* does not exist on Windows.
316 using ScopedDir = ScopedResource<DIR*, closedir, nullptr>;
317 #endif
318 
319 }  // namespace base
320 }  // namespace perfetto
321 
322 #endif  // INCLUDE_PERFETTO_EXT_BASE_SCOPED_FILE_H_
323 /*
324  * Copyright (C) 2018 The Android Open Source Project
325  *
326  * Licensed under the Apache License, Version 2.0 (the "License");
327  * you may not use this file except in compliance with the License.
328  * You may obtain a copy of the License at
329  *
330  *      http://www.apache.org/licenses/LICENSE-2.0
331  *
332  * Unless required by applicable law or agreed to in writing, software
333  * distributed under the License is distributed on an "AS IS" BASIS,
334  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
335  * See the License for the specific language governing permissions and
336  * limitations under the License.
337  */
338 
339 #ifndef INCLUDE_PERFETTO_EXT_BASE_EVENT_FD_H_
340 #define INCLUDE_PERFETTO_EXT_BASE_EVENT_FD_H_
341 
342 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
343 // gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
344 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
345 
346 namespace perfetto {
347 namespace base {
348 
349 // A waitable event that can be used with poll/select.
350 // This is really a wrapper around eventfd_create with a pipe-based fallback
351 // for other platforms where eventfd is not supported.
352 class EventFd {
353  public:
354   EventFd();
355   ~EventFd();
356   EventFd(EventFd&&) noexcept = default;
357   EventFd& operator=(EventFd&&) = default;
358 
359   // The non-blocking file descriptor that can be polled to wait for the event.
fd() const360   PlatformHandle fd() const { return event_handle_.get(); }
361 
362   // Can be called from any thread.
363   void Notify();
364 
365   // Can be called from any thread. If more Notify() are queued a Clear() call
366   // can clear all of them (up to 16 per call).
367   void Clear();
368 
369  private:
370   // The eventfd, when eventfd is supported, otherwise this is the read end of
371   // the pipe for fallback mode.
372   ScopedPlatformHandle event_handle_;
373 
374 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) &&   \
375     !PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
376     !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
377   // On Mac and other non-Linux UNIX platforms a pipe-based fallback is used.
378   // The write end of the wakeup pipe.
379   ScopedFile write_fd_;
380 #endif
381 };
382 
383 }  // namespace base
384 }  // namespace perfetto
385 
386 #endif  // INCLUDE_PERFETTO_EXT_BASE_EVENT_FD_H_
387 // gen_amalgamated begin header: include/perfetto/ext/base/pipe.h
388 /*
389  * Copyright (C) 2018 The Android Open Source Project
390  *
391  * Licensed under the Apache License, Version 2.0 (the "License");
392  * you may not use this file except in compliance with the License.
393  * You may obtain a copy of the License at
394  *
395  *      http://www.apache.org/licenses/LICENSE-2.0
396  *
397  * Unless required by applicable law or agreed to in writing, software
398  * distributed under the License is distributed on an "AS IS" BASIS,
399  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
400  * See the License for the specific language governing permissions and
401  * limitations under the License.
402  */
403 
404 #ifndef INCLUDE_PERFETTO_EXT_BASE_PIPE_H_
405 #define INCLUDE_PERFETTO_EXT_BASE_PIPE_H_
406 
407 // gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
408 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
409 
410 namespace perfetto {
411 namespace base {
412 
413 class Pipe {
414  public:
415   enum Flags {
416     kBothBlock = 0,
417 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
418     kBothNonBlock,
419     kRdNonBlock,
420     kWrNonBlock,
421 #endif
422   };
423 
424   static Pipe Create(Flags = kBothBlock);
425 
426   Pipe();
427   Pipe(Pipe&&) noexcept;
428   Pipe& operator=(Pipe&&);
429 
430   ScopedPlatformHandle rd;
431   ScopedPlatformHandle wr;
432 };
433 
434 }  // namespace base
435 }  // namespace perfetto
436 
437 #endif  // INCLUDE_PERFETTO_EXT_BASE_PIPE_H_
438 // gen_amalgamated begin header: include/perfetto/ext/base/utils.h
439 /*
440  * Copyright (C) 2017 The Android Open Source Project
441  *
442  * Licensed under the Apache License, Version 2.0 (the "License");
443  * you may not use this file except in compliance with the License.
444  * You may obtain a copy of the License at
445  *
446  *      http://www.apache.org/licenses/LICENSE-2.0
447  *
448  * Unless required by applicable law or agreed to in writing, software
449  * distributed under the License is distributed on an "AS IS" BASIS,
450  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
451  * See the License for the specific language governing permissions and
452  * limitations under the License.
453  */
454 
455 #ifndef INCLUDE_PERFETTO_EXT_BASE_UTILS_H_
456 #define INCLUDE_PERFETTO_EXT_BASE_UTILS_H_
457 
458 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
459 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
460 
461 #include <errno.h>
462 #include <stddef.h>
463 #include <stdint.h>
464 #include <stdlib.h>
465 #include <sys/types.h>
466 
467 #include <atomic>
468 #include <string>
469 
470 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
471 // Even if Windows has errno.h, the all syscall-restart behavior does not apply.
472 // Trying to handle EINTR can cause more harm than good if errno is left stale.
473 // Chromium does the same.
474 #define PERFETTO_EINTR(x) (x)
475 #else
476 #define PERFETTO_EINTR(x)                                   \
477   ([&] {                                                    \
478     decltype(x) eintr_wrapper_result;                       \
479     do {                                                    \
480       eintr_wrapper_result = (x);                           \
481     } while (eintr_wrapper_result == -1 && errno == EINTR); \
482     return eintr_wrapper_result;                            \
483   }())
484 #endif
485 
486 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
487 using uid_t = unsigned int;
488 #if !PERFETTO_BUILDFLAG(PERFETTO_COMPILER_GCC)
489 using pid_t = unsigned int;
490 #endif
491 #if defined(_WIN64)
492 using ssize_t = int64_t;
493 #else
494 using ssize_t = long;
495 #endif
496 #endif
497 
498 namespace perfetto {
499 namespace base {
500 
501 constexpr uid_t kInvalidUid = static_cast<uid_t>(-1);
502 constexpr pid_t kInvalidPid = static_cast<pid_t>(-1);
503 
504 // Do not add new usages of kPageSize, consider using GetSysPageSize() below.
505 // TODO(primiano): over time the semantic of kPageSize became too ambiguous.
506 // Strictly speaking, this constant is incorrect on some new devices where the
507 // page size can be 16K (e.g., crbug.com/1116576). Unfortunately too much code
508 // ended up depending on kPageSize for purposes that are not strictly related
509 // with the kernel's mm subsystem.
510 constexpr size_t kPageSize = 4096;
511 
512 // Returns the system's page size. Use this when dealing with mmap, madvise and
513 // similar mm-related syscalls.
514 uint32_t GetSysPageSize();
515 
516 template <typename T>
ArraySize(const T & array)517 constexpr size_t ArraySize(const T& array) {
518   return sizeof(array) / sizeof(array[0]);
519 }
520 
521 // Function object which invokes 'free' on its parameter, which must be
522 // a pointer. Can be used to store malloc-allocated pointers in std::unique_ptr:
523 //
524 // std::unique_ptr<int, base::FreeDeleter> foo_ptr(
525 //     static_cast<int*>(malloc(sizeof(int))));
526 struct FreeDeleter {
operator ()perfetto::base::FreeDeleter527   inline void operator()(void* ptr) const { free(ptr); }
528 };
529 
530 template <typename T>
AssumeLittleEndian(T value)531 constexpr T AssumeLittleEndian(T value) {
532 #if !PERFETTO_IS_LITTLE_ENDIAN()
533   static_assert(false, "Unimplemented on big-endian archs");
534 #endif
535   return value;
536 }
537 
538 // Round up |size| to a multiple of |alignment| (must be a power of two).
539 template <size_t alignment>
AlignUp(size_t size)540 constexpr size_t AlignUp(size_t size) {
541   static_assert((alignment & (alignment - 1)) == 0, "alignment must be a pow2");
542   return (size + alignment - 1) & ~(alignment - 1);
543 }
544 
IsAgain(int err)545 inline bool IsAgain(int err) {
546   return err == EAGAIN || err == EWOULDBLOCK;
547 }
548 
549 // setenv(2)-equivalent. Deals with Windows vs Posix discrepancies.
550 void SetEnv(const std::string& key, const std::string& value);
551 
552 // Calls mallopt(M_PURGE, 0) on Android. Does nothing on other platforms.
553 // This forces the allocator to release freed memory. This is used to work
554 // around various Scudo inefficiencies. See b/170217718.
555 void MaybeReleaseAllocatorMemToOS();
556 
557 // geteuid() on POSIX OSes, returns 0 on Windows (See comment in utils.cc).
558 uid_t GetCurrentUserId();
559 
560 // Forks the process.
561 // Parent: prints the PID of the child and exit(0).
562 // Child: redirects stdio onto /dev/null and chdirs into .
563 void Daemonize();
564 
565 }  // namespace base
566 }  // namespace perfetto
567 
568 #endif  // INCLUDE_PERFETTO_EXT_BASE_UTILS_H_
569 /*
570  * Copyright (C) 2018 The Android Open Source Project
571  *
572  * Licensed under the Apache License, Version 2.0 (the "License");
573  * you may not use this file except in compliance with the License.
574  * You may obtain a copy of the License at
575  *
576  *      http://www.apache.org/licenses/LICENSE-2.0
577  *
578  * Unless required by applicable law or agreed to in writing, software
579  * distributed under the License is distributed on an "AS IS" BASIS,
580  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
581  * See the License for the specific language governing permissions and
582  * limitations under the License.
583  */
584 
585 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
586 
587 #include <errno.h>
588 #include <stdint.h>
589 
590 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
591 #include <Windows.h>
592 #include <synchapi.h>
593 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
594     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
595 #include <sys/eventfd.h>
596 #include <unistd.h>
597 #else  // Mac, Fuchsia and other non-Linux UNIXes
598 #include <unistd.h>
599 #endif
600 
601 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
602 // gen_amalgamated expanded: #include "perfetto/ext/base/event_fd.h"
603 // gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
604 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
605 
606 namespace perfetto {
607 namespace base {
608 
609 EventFd::~EventFd() = default;
610 
611 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
EventFd()612 EventFd::EventFd() {
613   event_handle_.reset(
614       CreateEventA(/*lpEventAttributes=*/nullptr, /*bManualReset=*/true,
615                    /*bInitialState=*/false, /*bInitialState=*/nullptr));
616 }
617 
Notify()618 void EventFd::Notify() {
619   if (!SetEvent(event_handle_.get()))  // 0: fail, !0: success, unlike UNIX.
620     PERFETTO_DFATAL("EventFd::Notify()");
621 }
622 
Clear()623 void EventFd::Clear() {
624   if (!ResetEvent(event_handle_.get()))  // 0: fail, !0: success, unlike UNIX.
625     PERFETTO_DFATAL("EventFd::Clear()");
626 }
627 
628 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
629     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
630 
EventFd()631 EventFd::EventFd() {
632   event_handle_.reset(eventfd(/*initval=*/0, EFD_CLOEXEC | EFD_NONBLOCK));
633   PERFETTO_CHECK(event_handle_);
634 }
635 
Notify()636 void EventFd::Notify() {
637   const uint64_t value = 1;
638   ssize_t ret = write(event_handle_.get(), &value, sizeof(value));
639   if (ret <= 0 && errno != EAGAIN)
640     PERFETTO_DFATAL("EventFd::Notify()");
641 }
642 
Clear()643 void EventFd::Clear() {
644   uint64_t value;
645   ssize_t ret = read(event_handle_.get(), &value, sizeof(value));
646   if (ret <= 0 && errno != EAGAIN)
647     PERFETTO_DFATAL("EventFd::Clear()");
648 }
649 
650 #else
651 
EventFd()652 EventFd::EventFd() {
653   // Make the pipe non-blocking so that we never block the waking thread (either
654   // the main thread or another one) when scheduling a wake-up.
655   Pipe pipe = Pipe::Create(Pipe::kBothNonBlock);
656   event_handle_ = ScopedPlatformHandle(std::move(pipe.rd).release());
657   write_fd_ = std::move(pipe.wr);
658 }
659 
Notify()660 void EventFd::Notify() {
661   const uint64_t value = 1;
662   ssize_t ret = write(write_fd_.get(), &value, sizeof(uint8_t));
663   if (ret <= 0 && errno != EAGAIN)
664     PERFETTO_DFATAL("EventFd::Notify()");
665 }
666 
Clear()667 void EventFd::Clear() {
668   // Drain the byte(s) written to the wake-up pipe. We can potentially read
669   // more than one byte if several wake-ups have been scheduled.
670   char buffer[16];
671   ssize_t ret = read(event_handle_.get(), &buffer[0], sizeof(buffer));
672   if (ret <= 0 && errno != EAGAIN)
673     PERFETTO_DFATAL("EventFd::Clear()");
674 }
675 #endif
676 
677 }  // namespace base
678 }  // namespace perfetto
679 // gen_amalgamated begin source: src/base/file_utils.cc
680 // gen_amalgamated begin header: include/perfetto/ext/base/file_utils.h
681 /*
682  * Copyright (C) 2018 The Android Open Source Project
683  *
684  * Licensed under the Apache License, Version 2.0 (the "License");
685  * you may not use this file except in compliance with the License.
686  * You may obtain a copy of the License at
687  *
688  *      http://www.apache.org/licenses/LICENSE-2.0
689  *
690  * Unless required by applicable law or agreed to in writing, software
691  * distributed under the License is distributed on an "AS IS" BASIS,
692  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
693  * See the License for the specific language governing permissions and
694  * limitations under the License.
695  */
696 
697 #ifndef INCLUDE_PERFETTO_EXT_BASE_FILE_UTILS_H_
698 #define INCLUDE_PERFETTO_EXT_BASE_FILE_UTILS_H_
699 
700 #include <fcntl.h>  // For mode_t & O_RDONLY/RDWR. Exists also on Windows.
701 #include <stddef.h>
702 
703 #include <string>
704 
705 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
706 // gen_amalgamated expanded: #include "perfetto/base/export.h"
707 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
708 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
709 
710 namespace perfetto {
711 namespace base {
712 
713 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
714 using FileOpenMode = int;
715 #else
716 using FileOpenMode = mode_t;
717 #endif
718 
719 constexpr FileOpenMode kFileModeInvalid = static_cast<FileOpenMode>(-1);
720 
721 bool ReadPlatformHandle(PlatformHandle, std::string* out);
722 bool ReadFileDescriptor(int fd, std::string* out);
723 bool ReadFileStream(FILE* f, std::string* out);
724 bool ReadFile(const std::string& path, std::string* out);
725 
726 // A wrapper around read(2). It deals with Linux vs Windows includes. It also
727 // deals with handling EINTR. Has the same semantics of UNIX's read(2).
728 ssize_t Read(int fd, void* dst, size_t dst_size);
729 
730 // Call write until all data is written or an error is detected.
731 //
732 // man 2 write:
733 //   If a write() is interrupted by a signal handler before any bytes are
734 //   written, then the call fails with the error EINTR; if it is
735 //   interrupted after at least one byte has been written, the call
736 //   succeeds, and returns the number of bytes written.
737 ssize_t WriteAll(int fd, const void* buf, size_t count);
738 
739 ssize_t WriteAllHandle(PlatformHandle, const void* buf, size_t count);
740 
741 ScopedFile OpenFile(const std::string& path,
742                     int flags,
743                     FileOpenMode = kFileModeInvalid);
744 
745 // This is an alias for close(). It's to avoid leaking Windows.h in headers.
746 // Exported because ScopedFile is used in the /include/ext API by Chromium
747 // component builds.
748 int PERFETTO_EXPORT CloseFile(int fd);
749 
750 bool FlushFile(int fd);
751 
752 // Returns true if mkdir succeeds, false if it fails (see errno in that case).
753 bool Mkdir(const std::string& path);
754 
755 // Calls rmdir() on UNIX, _rmdir() on Windows.
756 bool Rmdir(const std::string& path);
757 
758 // Wrapper around access(path, F_OK).
759 bool FileExists(const std::string& path);
760 
761 }  // namespace base
762 }  // namespace perfetto
763 
764 #endif  // INCLUDE_PERFETTO_EXT_BASE_FILE_UTILS_H_
765 /*
766  * Copyright (C) 2018 The Android Open Source Project
767  *
768  * Licensed under the Apache License, Version 2.0 (the "License");
769  * you may not use this file except in compliance with the License.
770  * You may obtain a copy of the License at
771  *
772  *      http://www.apache.org/licenses/LICENSE-2.0
773  *
774  * Unless required by applicable law or agreed to in writing, software
775  * distributed under the License is distributed on an "AS IS" BASIS,
776  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
777  * See the License for the specific language governing permissions and
778  * limitations under the License.
779  */
780 
781 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
782 
783 #include <sys/stat.h>
784 #include <sys/types.h>
785 
786 #include <algorithm>
787 
788 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
789 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
790 // gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
791 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
792 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
793 
794 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
795 #include <Windows.h>
796 #include <direct.h>
797 #include <io.h>
798 #else
799 #include <dirent.h>
800 #include <unistd.h>
801 #endif
802 
803 namespace perfetto {
804 namespace base {
805 namespace {
806 constexpr size_t kBufSize = 2048;
807 }
808 
Read(int fd,void * dst,size_t dst_size)809 ssize_t Read(int fd, void* dst, size_t dst_size) {
810 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
811   return _read(fd, dst, static_cast<unsigned>(dst_size));
812 #else
813   return PERFETTO_EINTR(read(fd, dst, dst_size));
814 #endif
815 }
816 
ReadFileDescriptor(int fd,std::string * out)817 bool ReadFileDescriptor(int fd, std::string* out) {
818   // Do not override existing data in string.
819   size_t i = out->size();
820 
821   struct stat buf {};
822   if (fstat(fd, &buf) != -1) {
823     if (buf.st_size > 0)
824       out->resize(i + static_cast<size_t>(buf.st_size));
825   }
826 
827   ssize_t bytes_read;
828   for (;;) {
829     if (out->size() < i + kBufSize)
830       out->resize(out->size() + kBufSize);
831 
832     bytes_read = Read(fd, &((*out)[i]), kBufSize);
833     if (bytes_read > 0) {
834       i += static_cast<size_t>(bytes_read);
835     } else {
836       out->resize(i);
837       return bytes_read == 0;
838     }
839   }
840 }
841 
ReadPlatformHandle(PlatformHandle h,std::string * out)842 bool ReadPlatformHandle(PlatformHandle h, std::string* out) {
843 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
844   // Do not override existing data in string.
845   size_t i = out->size();
846 
847   for (;;) {
848     if (out->size() < i + kBufSize)
849       out->resize(out->size() + kBufSize);
850     DWORD bytes_read = 0;
851     auto res = ::ReadFile(h, &((*out)[i]), kBufSize, &bytes_read, nullptr);
852     if (res && bytes_read > 0) {
853       i += static_cast<size_t>(bytes_read);
854     } else {
855       out->resize(i);
856       const bool is_eof = res && bytes_read == 0;
857       auto err = res ? 0 : GetLastError();
858       // The "Broken pipe" error on Windows is slighly different than Unix:
859       // On Unix: a "broken pipe" error can happen only on the writer side. On
860       // the reader there is no broken pipe, just a EOF.
861       // On windows: the reader also sees a broken pipe error.
862       // Here we normalize on the Unix behavior, treating broken pipe as EOF.
863       return is_eof || err == ERROR_BROKEN_PIPE;
864     }
865   }
866 #else
867   return ReadFileDescriptor(h, out);
868 #endif
869 }
870 
ReadFileStream(FILE * f,std::string * out)871 bool ReadFileStream(FILE* f, std::string* out) {
872   return ReadFileDescriptor(fileno(f), out);
873 }
874 
ReadFile(const std::string & path,std::string * out)875 bool ReadFile(const std::string& path, std::string* out) {
876   base::ScopedFile fd = base::OpenFile(path, O_RDONLY);
877   if (!fd)
878     return false;
879 
880   return ReadFileDescriptor(*fd, out);
881 }
882 
WriteAll(int fd,const void * buf,size_t count)883 ssize_t WriteAll(int fd, const void* buf, size_t count) {
884   size_t written = 0;
885   while (written < count) {
886     // write() on windows takes an unsigned int size.
887     uint32_t bytes_left = static_cast<uint32_t>(
888         std::min(count - written, static_cast<size_t>(UINT32_MAX)));
889     ssize_t wr = PERFETTO_EINTR(
890         write(fd, static_cast<const char*>(buf) + written, bytes_left));
891     if (wr == 0)
892       break;
893     if (wr < 0)
894       return wr;
895     written += static_cast<size_t>(wr);
896   }
897   return static_cast<ssize_t>(written);
898 }
899 
WriteAllHandle(PlatformHandle h,const void * buf,size_t count)900 ssize_t WriteAllHandle(PlatformHandle h, const void* buf, size_t count) {
901 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
902   DWORD wsize = 0;
903   if (::WriteFile(h, buf, static_cast<DWORD>(count), &wsize, nullptr)) {
904     return wsize;
905   } else {
906     return -1;
907   }
908 #else
909   return WriteAll(h, buf, count);
910 #endif
911 }
912 
FlushFile(int fd)913 bool FlushFile(int fd) {
914   PERFETTO_DCHECK(fd != 0);
915 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
916     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
917   return !PERFETTO_EINTR(fdatasync(fd));
918 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
919   return !PERFETTO_EINTR(_commit(fd));
920 #else
921   return !PERFETTO_EINTR(fsync(fd));
922 #endif
923 }
924 
Mkdir(const std::string & path)925 bool Mkdir(const std::string& path) {
926 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
927   return _mkdir(path.c_str()) == 0;
928 #else
929   return mkdir(path.c_str(), 0755) == 0;
930 #endif
931 }
932 
Rmdir(const std::string & path)933 bool Rmdir(const std::string& path) {
934 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
935   return _rmdir(path.c_str()) == 0;
936 #else
937   return rmdir(path.c_str()) == 0;
938 #endif
939 }
940 
CloseFile(int fd)941 int CloseFile(int fd) {
942   return close(fd);
943 }
944 
OpenFile(const std::string & path,int flags,FileOpenMode mode)945 ScopedFile OpenFile(const std::string& path, int flags, FileOpenMode mode) {
946   PERFETTO_DCHECK((flags & O_CREAT) == 0 || mode != kFileModeInvalid);
947 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
948   // Always use O_BINARY on Windows, to avoid silly EOL translations.
949   ScopedFile fd(_open(path.c_str(), flags | O_BINARY, mode));
950 #else
951   // Always open a ScopedFile with O_CLOEXEC so we can safely fork and exec.
952   ScopedFile fd(open(path.c_str(), flags | O_CLOEXEC, mode));
953 #endif
954   return fd;
955 }
956 
FileExists(const std::string & path)957 bool FileExists(const std::string& path) {
958 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
959   return _access(path.c_str(), 0) == 0;
960 #else
961   return access(path.c_str(), F_OK) == 0;
962 #endif
963 }
964 
965 // Declared in base/platform_handle.h.
ClosePlatformHandle(PlatformHandle handle)966 int ClosePlatformHandle(PlatformHandle handle) {
967 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
968   // Make the return value UNIX-style.
969   return CloseHandle(handle) ? 0 : -1;
970 #else
971   return close(handle);
972 #endif
973 }
974 
975 }  // namespace base
976 }  // namespace perfetto
977 // gen_amalgamated begin source: src/base/getopt_compat.cc
978 // gen_amalgamated begin header: include/perfetto/ext/base/getopt_compat.h
979 /*
980  * Copyright (C) 2021 The Android Open Source Project
981  *
982  * Licensed under the Apache License, Version 2.0 (the "License");
983  * you may not use this file except in compliance with the License.
984  * You may obtain a copy of the License at
985  *
986  *      http://www.apache.org/licenses/LICENSE-2.0
987  *
988  * Unless required by applicable law or agreed to in writing, software
989  * distributed under the License is distributed on an "AS IS" BASIS,
990  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
991  * See the License for the specific language governing permissions and
992  * limitations under the License.
993  */
994 
995 #ifndef INCLUDE_PERFETTO_EXT_BASE_GETOPT_COMPAT_H_
996 #define INCLUDE_PERFETTO_EXT_BASE_GETOPT_COMPAT_H_
997 
998 #include <cstddef>  // For std::nullptr_t
999 
1000 // No translation units other than base/getopt.h and getopt_compat_unittest.cc
1001 // should directly include this file. Use base/getopt.h instead.
1002 
1003 namespace perfetto {
1004 namespace base {
1005 namespace getopt_compat {
1006 
1007 // A tiny getopt() replacement for Windows, which doesn't have <getopt.h>.
1008 // This implementation is based on the subset of features that we use in the
1009 // Perfetto codebase. It doesn't even try to deal with the full surface of GNU's
1010 // getopt().
1011 // Limitations:
1012 // - getopt_long_only() is not supported.
1013 // - optional_argument is not supported. That is extremely subtle and caused us
1014 //   problems in the past with GNU's getopt.
1015 // - It does not reorder non-option arguments. It behaves like MacOS getopt, or
1016 //   GNU's when POSIXLY_CORRECT=1.
1017 // - Doesn't expose optopt or opterr.
1018 // - option.flag and longindex are not supported and must be nullptr.
1019 
1020 enum {
1021   no_argument = 0,
1022   required_argument = 1,
1023 };
1024 
1025 struct option {
1026   const char* name;
1027   int has_arg;
1028   std::nullptr_t flag;  // Only nullptr is supported.
1029   int val;
1030 };
1031 
1032 extern char* optarg;
1033 extern int optind;
1034 
1035 int getopt_long(int argc,
1036                 char** argv,
1037                 const char* shortopts,
1038                 const option* longopts,
1039                 std::nullptr_t /*longindex is not supported*/);
1040 
1041 int getopt(int argc, char** argv, const char* shortopts);
1042 
1043 }  // namespace getopt_compat
1044 }  // namespace base
1045 }  // namespace perfetto
1046 
1047 #endif  // INCLUDE_PERFETTO_EXT_BASE_GETOPT_COMPAT_H_
1048 /*
1049  * Copyright (C) 2021 The Android Open Source Project
1050  *
1051  * Licensed under the Apache License, Version 2.0 (the "License");
1052  * you may not use this file except in compliance with the License.
1053  * You may obtain a copy of the License at
1054  *
1055  *      http://www.apache.org/licenses/LICENSE-2.0
1056  *
1057  * Unless required by applicable law or agreed to in writing, software
1058  * distributed under the License is distributed on an "AS IS" BASIS,
1059  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1060  * See the License for the specific language governing permissions and
1061  * limitations under the License.
1062  */
1063 
1064 // gen_amalgamated expanded: #include "perfetto/ext/base/getopt_compat.h"
1065 
1066 #include <stdio.h>
1067 #include <stdlib.h>
1068 #include <string.h>
1069 
1070 #include <vector>
1071 
1072 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
1073 
1074 namespace perfetto {
1075 namespace base {
1076 namespace getopt_compat {
1077 
1078 char* optarg = nullptr;
1079 int optind = 0;
1080 
1081 namespace {
1082 
1083 char* nextchar = nullptr;
1084 
LookupLongOpt(const std::vector<option> & opts,const char * name,size_t len)1085 const option* LookupLongOpt(const std::vector<option>& opts,
1086                             const char* name,
1087                             size_t len) {
1088   for (const option& opt : opts) {
1089     if (strncmp(opt.name, name, len) == 0 && strlen(opt.name) == len)
1090       return &opt;
1091   }
1092   return nullptr;
1093 }
1094 
LookupShortOpt(const std::vector<option> & opts,char c)1095 const option* LookupShortOpt(const std::vector<option>& opts, char c) {
1096   for (const option& opt : opts) {
1097     if (opt.name == nullptr && opt.val == c)
1098       return &opt;
1099   }
1100   return nullptr;
1101 }
1102 
ParseOpts(const char * shortopts,const option * longopts,std::vector<option> * res)1103 bool ParseOpts(const char* shortopts,
1104                const option* longopts,
1105                std::vector<option>* res) {
1106   // Parse long options first.
1107   for (const option* lopt = longopts; lopt && lopt->name; lopt++) {
1108     PERFETTO_CHECK(lopt->flag == nullptr);
1109     PERFETTO_CHECK(lopt->has_arg == no_argument ||
1110                    lopt->has_arg == required_argument);
1111     res->emplace_back(*lopt);
1112   }
1113 
1114   // Merge short options.
1115   for (const char* sopt = shortopts; sopt && *sopt;) {
1116     const size_t idx = static_cast<size_t>(sopt - shortopts);
1117     char c = *sopt++;
1118     bool valid = (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
1119                  (c >= '0' && c <= '9');
1120     if (!valid) {
1121       fprintf(stderr,
1122               "Error parsing shortopts. Unexpected char '%c' at offset %zu\n",
1123               c, idx);
1124       return false;
1125     }
1126     res->emplace_back();
1127     option& opt = res->back();
1128     opt.val = c;
1129     opt.has_arg = no_argument;
1130     if (*sopt == ':') {
1131       opt.has_arg = required_argument;
1132       ++sopt;
1133     }
1134   }
1135   return true;
1136 }
1137 
1138 }  // namespace
1139 
getopt_long(int argc,char ** argv,const char * shortopts,const option * longopts,std::nullptr_t)1140 int getopt_long(int argc,
1141                 char** argv,
1142                 const char* shortopts,
1143                 const option* longopts,
1144                 std::nullptr_t /*longind*/) {
1145   std::vector<option> opts;
1146   optarg = nullptr;
1147 
1148   if (optind == 0)
1149     optind = 1;
1150 
1151   if (optind >= argc)
1152     return -1;
1153 
1154   if (!ParseOpts(shortopts, longopts, &opts))
1155     return '?';
1156 
1157   char* arg = argv[optind];
1158 
1159   if (!nextchar) {
1160     // If |nextchar| is null we are NOT in the middle of a short option and we
1161     // should parse the next argv.
1162     if (strncmp(arg, "--", 2) == 0 && strlen(arg) > 2) {
1163       // A --long option.
1164       arg += 2;
1165       char* sep = strchr(arg, '=');
1166       optind++;
1167 
1168       size_t len = sep ? static_cast<size_t>(sep - arg) : strlen(arg);
1169       const option* opt = LookupLongOpt(opts, arg, len);
1170       if (!opt) {
1171         fprintf(stderr, "unrecognized option '--%s'\n", arg);
1172         return '?';
1173       }
1174 
1175       if (opt->has_arg == no_argument) {
1176         if (sep) {
1177           fprintf(stderr, "option '--%s' doesn't allow an argument\n", arg);
1178           return '?';
1179         } else {
1180           return opt->val;
1181         }
1182       } else if (opt->has_arg == required_argument) {
1183         if (sep) {
1184           optarg = sep + 1;
1185           return opt->val;
1186         } else if (optind >= argc) {
1187           fprintf(stderr, "option '--%s' requires an argument\n", arg);
1188           return '?';
1189         } else {
1190           optarg = argv[optind++];
1191           return opt->val;
1192         }
1193       }
1194       // has_arg must be either |no_argument| or |required_argument|. We
1195       // shoulnd't get here unless the check in ParseOpts() has a bug.
1196       PERFETTO_CHECK(false);
1197     }  // if (arg ~= "--*").
1198 
1199     if (strlen(arg) > 1 && arg[0] == '-' && arg[1] != '-') {
1200       // A sequence of short options. Parsing logic continues below.
1201       nextchar = &arg[1];
1202     }
1203   }  // if(!nextchar)
1204 
1205   if (nextchar) {
1206     // At this point either:
1207     // 1. This is the first char of a sequence of short options, and we fell
1208     //    through here from the lines above.
1209     // 2. This is the N (>1) char of a sequence of short options, and we got
1210     //    here from a new getopt() call to getopt().
1211     const char cur_char = *nextchar;
1212     PERFETTO_CHECK(cur_char != '\0');
1213 
1214     // Advance the option char in any case, before we start reasoning on them.
1215     // if we got to the end of the "-abc" sequence, increment optind so the next
1216     // getopt() call resumes from the next argv argument.
1217     if (*(++nextchar) == '\0') {
1218       nextchar = nullptr;
1219       ++optind;
1220     }
1221 
1222     const option* opt = LookupShortOpt(opts, cur_char);
1223     if (!opt) {
1224       fprintf(stderr, "invalid option -- '%c'\n", cur_char);
1225       return '?';
1226     }
1227     if (opt->has_arg == no_argument) {
1228       return cur_char;
1229     } else if (opt->has_arg == required_argument) {
1230       // This is a subtle getopt behavior. Say you call `tar -fx`, there are
1231       // two cases:
1232       // 1. If 'f' is no_argument then 'x' (and anything else after) is
1233       //    interpreted as an independent argument (like `tar -f -x`).
1234       // 2. If 'f' is required_argument, than everything else after the 'f'
1235       //    is interpreted as the option argument (like `tar -f x`)
1236       if (!nextchar) {
1237         // Case 1.
1238         if (optind >= argc) {
1239           fprintf(stderr, "option requires an argument -- '%c'\n", cur_char);
1240           return '?';
1241         } else {
1242           optarg = argv[optind++];
1243           return cur_char;
1244         }
1245       } else {
1246         // Case 2.
1247         optarg = nextchar;
1248         nextchar = nullptr;
1249         optind++;
1250         return cur_char;
1251       }
1252     }
1253     PERFETTO_CHECK(false);
1254   }  // if (nextchar)
1255 
1256   // If we get here, we found the first non-option argument. Stop here.
1257 
1258   if (strcmp(arg, "--") == 0)
1259     optind++;
1260 
1261   return -1;
1262 }
1263 
getopt(int argc,char ** argv,const char * shortopts)1264 int getopt(int argc, char** argv, const char* shortopts) {
1265   return getopt_long(argc, argv, shortopts, nullptr, nullptr);
1266 }
1267 
1268 }  // namespace getopt_compat
1269 }  // namespace base
1270 }  // namespace perfetto
1271 // gen_amalgamated begin source: src/base/logging.cc
1272 /*
1273  * Copyright (C) 2019 The Android Open Source Project
1274  *
1275  * Licensed under the Apache License, Version 2.0 (the "License");
1276  * you may not use this file except in compliance with the License.
1277  * You may obtain a copy of the License at
1278  *
1279  *      http://www.apache.org/licenses/LICENSE-2.0
1280  *
1281  * Unless required by applicable law or agreed to in writing, software
1282  * distributed under the License is distributed on an "AS IS" BASIS,
1283  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1284  * See the License for the specific language governing permissions and
1285  * limitations under the License.
1286  */
1287 
1288 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
1289 
1290 #include <stdarg.h>
1291 #include <stdio.h>
1292 
1293 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1294 #include <unistd.h>  // For isatty()
1295 #endif
1296 
1297 #include <atomic>
1298 #include <memory>
1299 
1300 // gen_amalgamated expanded: #include "perfetto/base/time.h"
1301 
1302 namespace perfetto {
1303 namespace base {
1304 
1305 namespace {
1306 const char kReset[] = "\x1b[0m";
1307 const char kDefault[] = "\x1b[39m";
1308 const char kDim[] = "\x1b[2m";
1309 const char kRed[] = "\x1b[31m";
1310 const char kBoldGreen[] = "\x1b[1m\x1b[32m";
1311 const char kLightGray[] = "\x1b[90m";
1312 
1313 std::atomic<LogMessageCallback> g_log_callback{};
1314 
1315 }  // namespace
1316 
SetLogMessageCallback(LogMessageCallback callback)1317 void SetLogMessageCallback(LogMessageCallback callback) {
1318   g_log_callback.store(callback, std::memory_order_relaxed);
1319 }
1320 
LogMessage(LogLev level,const char * fname,int line,const char * fmt,...)1321 void LogMessage(LogLev level,
1322                 const char* fname,
1323                 int line,
1324                 const char* fmt,
1325                 ...) {
1326   char stack_buf[512];
1327   std::unique_ptr<char[]> large_buf;
1328   char* log_msg = &stack_buf[0];
1329 
1330   // By default use a stack allocated buffer because most log messages are quite
1331   // short. In rare cases they can be larger (e.g. --help). In those cases we
1332   // pay the cost of allocating the buffer on the heap.
1333   for (size_t max_len = sizeof(stack_buf);;) {
1334     va_list args;
1335     va_start(args, fmt);
1336     int res = vsnprintf(log_msg, max_len, fmt, args);
1337     va_end(args);
1338 
1339     // If for any reason the print fails, overwrite the message but still print
1340     // it. The code below will attach the filename and line, which is still
1341     // useful.
1342     if (res < 0) {
1343       strncpy(log_msg, "[printf format error]", max_len);
1344       break;
1345     }
1346 
1347     // if res == max_len, vsnprintf saturated the input buffer. Retry with a
1348     // larger buffer in that case (within reasonable limits).
1349     if (res < static_cast<int>(max_len) || max_len >= 128 * 1024)
1350       break;
1351     max_len *= 4;
1352     large_buf.reset(new char[max_len]);
1353     log_msg = &large_buf[0];
1354   }
1355 
1356   LogMessageCallback cb = g_log_callback.load(std::memory_order_relaxed);
1357   if (cb) {
1358     cb({level, line, fname, log_msg});
1359     return;
1360   }
1361 
1362   const char* color = kDefault;
1363   switch (level) {
1364     case kLogDebug:
1365       color = kDim;
1366       break;
1367     case kLogInfo:
1368       color = kDefault;
1369       break;
1370     case kLogImportant:
1371       color = kBoldGreen;
1372       break;
1373     case kLogError:
1374       color = kRed;
1375       break;
1376   }
1377 
1378 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
1379     !PERFETTO_BUILDFLAG(PERFETTO_OS_WASM)
1380   static const bool use_colors = isatty(STDERR_FILENO);
1381 #else
1382   static const bool use_colors = false;
1383 #endif
1384 
1385   // Formats file.cc:line as a space-padded fixed width string. If the file name
1386   // |fname| is too long, truncate it on the left-hand side.
1387   char line_str[10];
1388   size_t line_len =
1389       static_cast<size_t>(snprintf(line_str, sizeof(line_str), "%d", line));
1390 
1391   // 24 will be the width of the file.cc:line column in the log event.
1392   char file_and_line[24];
1393   size_t fname_len = strlen(fname);
1394   size_t fname_max = sizeof(file_and_line) - line_len - 2;  // 2 = ':' + '\0'.
1395   size_t fname_offset = fname_len <= fname_max ? 0 : fname_len - fname_max;
1396   int len = snprintf(file_and_line, sizeof(file_and_line), "%s:%s",
1397                      fname + fname_offset, line_str);
1398   memset(&file_and_line[len], ' ', sizeof(file_and_line) - size_t(len));
1399   file_and_line[sizeof(file_and_line) - 1] = '\0';
1400 
1401 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
1402   // Logcat has already timestamping, don't re-emit it.
1403   __android_log_print(ANDROID_LOG_DEBUG + level, "perfetto", "%s %s",
1404                       file_and_line, log_msg);
1405 #endif
1406 
1407   // When printing on stderr, print also the timestamp. We don't really care
1408   // about the actual time. We just need some reference clock that can be used
1409   // to correlated events across differrent processses (e.g. traced and
1410   // traced_probes). The wall time % 1000 is good enough.
1411   char timestamp[32];
1412   uint32_t t_ms = static_cast<uint32_t>(GetWallTimeMs().count());
1413   uint32_t t_sec = t_ms / 1000;
1414   t_ms -= t_sec * 1000;
1415   t_sec = t_sec % 1000;
1416   snprintf(timestamp, sizeof(timestamp), "[%03u.%03u] ", t_sec, t_ms);
1417 
1418   if (use_colors) {
1419     fprintf(stderr, "%s%s%s%s %s%s%s\n", kLightGray, timestamp, file_and_line,
1420             kReset, color, log_msg, kReset);
1421   } else {
1422     fprintf(stderr, "%s%s %s\n", timestamp, file_and_line, log_msg);
1423   }
1424 }
1425 
1426 }  // namespace base
1427 }  // namespace perfetto
1428 // gen_amalgamated begin source: src/base/metatrace.cc
1429 // gen_amalgamated begin header: include/perfetto/ext/base/metatrace.h
1430 // gen_amalgamated begin header: include/perfetto/ext/base/metatrace_events.h
1431 /*
1432  * Copyright (C) 2019 The Android Open Source Project
1433  *
1434  * Licensed under the Apache License, Version 2.0 (the "License");
1435  * you may not use this file except in compliance with the License.
1436  * You may obtain a copy of the License at
1437  *
1438  *      http://www.apache.org/licenses/LICENSE-2.0
1439  *
1440  * Unless required by applicable law or agreed to in writing, software
1441  * distributed under the License is distributed on an "AS IS" BASIS,
1442  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1443  * See the License for the specific language governing permissions and
1444  * limitations under the License.
1445  */
1446 
1447 #ifndef INCLUDE_PERFETTO_EXT_BASE_METATRACE_EVENTS_H_
1448 #define INCLUDE_PERFETTO_EXT_BASE_METATRACE_EVENTS_H_
1449 
1450 #include <stdint.h>
1451 
1452 namespace perfetto {
1453 namespace metatrace {
1454 
1455 enum Tags : uint32_t {
1456   TAG_NONE = 0,
1457   TAG_ANY = uint32_t(-1),
1458   TAG_FTRACE = 1 << 0,
1459   TAG_PROC_POLLERS = 1 << 1,
1460   TAG_TRACE_WRITER = 1 << 2,
1461   TAG_TRACE_SERVICE = 1 << 3,
1462   TAG_PRODUCER = 1 << 4,
1463 };
1464 
1465 // The macros below generate matching enums and arrays of string literals.
1466 // This is to avoid maintaining string maps manually.
1467 
1468 // clang-format off
1469 
1470 // DO NOT remove or reshuffle items in this list, only append. The ID of these
1471 // events are an ABI, the trace processor relies on these to open old traces.
1472 #define PERFETTO_METATRACE_EVENTS(F) \
1473   F(EVENT_ZERO_UNUSED), \
1474   F(FTRACE_CPU_READER_READ), /*unused*/ \
1475   F(FTRACE_DRAIN_CPUS), /*unused*/ \
1476   F(FTRACE_UNBLOCK_READERS), /*unused*/ \
1477   F(FTRACE_CPU_READ_NONBLOCK), /*unused*/ \
1478   F(FTRACE_CPU_READ_BLOCK), /*unused*/ \
1479   F(FTRACE_CPU_SPLICE_NONBLOCK), /*unused*/ \
1480   F(FTRACE_CPU_SPLICE_BLOCK), /*unused*/ \
1481   F(FTRACE_CPU_WAIT_CMD), /*unused*/ \
1482   F(FTRACE_CPU_RUN_CYCLE), /*unused*/ \
1483   F(FTRACE_CPU_FLUSH), \
1484   F(FTRACE_CPU_DRAIN), /*unused*/ \
1485   F(READ_SYS_STATS), \
1486   F(PS_WRITE_ALL_PROCESSES), \
1487   F(PS_ON_PIDS), \
1488   F(PS_ON_RENAME_PIDS), \
1489   F(PS_WRITE_ALL_PROCESS_STATS), \
1490   F(TRACE_WRITER_COMMIT_STARTUP_WRITER_BATCH), \
1491   F(FTRACE_READ_TICK), \
1492   F(FTRACE_CPU_READ_CYCLE), \
1493   F(FTRACE_CPU_READ_BATCH), \
1494   F(KALLSYMS_PARSE), \
1495   F(PROFILER_READ_TICK), \
1496   F(PROFILER_READ_CPU), \
1497   F(PROFILER_UNWIND_TICK), \
1498   F(PROFILER_UNWIND_SAMPLE), \
1499   F(PROFILER_UNWIND_INITIAL_ATTEMPT), \
1500   F(PROFILER_UNWIND_ATTEMPT), \
1501   F(PROFILER_MAPS_PARSE), \
1502   F(PROFILER_MAPS_REPARSE), \
1503   F(PROFILER_UNWIND_CACHE_CLEAR)
1504 
1505 // Append only, see above.
1506 //
1507 // Values that aren't used as counters:
1508 // * FTRACE_SERVICE_COMMIT_DATA is a bit-packed representation of an event, see
1509 //   tracing_service_impl.cc for the format.
1510 // * PROFILER_UNWIND_CURRENT_PID represents the PID that is being unwound.
1511 //
1512 #define PERFETTO_METATRACE_COUNTERS(F) \
1513   F(COUNTER_ZERO_UNUSED),\
1514   F(FTRACE_PAGES_DRAINED), \
1515   F(PS_PIDS_SCANNED), \
1516   F(TRACE_SERVICE_COMMIT_DATA), \
1517   F(PROFILER_UNWIND_QUEUE_SZ), \
1518   F(PROFILER_UNWIND_CURRENT_PID)
1519 
1520 // clang-format on
1521 
1522 #define PERFETTO_METATRACE_IDENTITY(name) name
1523 #define PERFETTO_METATRACE_TOSTRING(name) #name
1524 
1525 enum Events : uint16_t {
1526   PERFETTO_METATRACE_EVENTS(PERFETTO_METATRACE_IDENTITY),
1527   EVENTS_MAX
1528 };
1529 constexpr char const* kEventNames[] = {
1530     PERFETTO_METATRACE_EVENTS(PERFETTO_METATRACE_TOSTRING)};
1531 
1532 enum Counters : uint16_t {
1533   PERFETTO_METATRACE_COUNTERS(PERFETTO_METATRACE_IDENTITY),
1534   COUNTERS_MAX
1535 };
1536 constexpr char const* kCounterNames[] = {
1537     PERFETTO_METATRACE_COUNTERS(PERFETTO_METATRACE_TOSTRING)};
1538 
SuppressUnusedVarsInAmalgamatedBuild()1539 inline void SuppressUnusedVarsInAmalgamatedBuild() {
1540   (void)kCounterNames;
1541   (void)kEventNames;
1542 }
1543 
1544 }  // namespace metatrace
1545 }  // namespace perfetto
1546 
1547 #endif  // INCLUDE_PERFETTO_EXT_BASE_METATRACE_EVENTS_H_
1548 /*
1549  * Copyright (C) 2019 The Android Open Source Project
1550  *
1551  * Licensed under the Apache License, Version 2.0 (the "License");
1552  * you may not use this file except in compliance with the License.
1553  * You may obtain a copy of the License at
1554  *
1555  *      http://www.apache.org/licenses/LICENSE-2.0
1556  *
1557  * Unless required by applicable law or agreed to in writing, software
1558  * distributed under the License is distributed on an "AS IS" BASIS,
1559  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1560  * See the License for the specific language governing permissions and
1561  * limitations under the License.
1562  */
1563 
1564 #ifndef INCLUDE_PERFETTO_EXT_BASE_METATRACE_H_
1565 #define INCLUDE_PERFETTO_EXT_BASE_METATRACE_H_
1566 
1567 #include <array>
1568 #include <atomic>
1569 #include <functional>
1570 #include <string>
1571 
1572 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
1573 // gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
1574 // gen_amalgamated expanded: #include "perfetto/base/time.h"
1575 // gen_amalgamated expanded: #include "perfetto/ext/base/metatrace_events.h"
1576 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
1577 
1578 // A facility to trace execution of the perfetto codebase itself.
1579 // The meta-tracing framework is organized into three layers:
1580 //
1581 // 1. A static ring-buffer in base/ (this file) that supports concurrent writes
1582 //    and a single reader.
1583 //    The responsibility of this layer is to store events and counters as
1584 //    efficiently as possible without re-entering any tracing code.
1585 //    This is really a static-storage-based ring-buffer based on a POD array.
1586 //    This layer does NOT deal with serializing the meta-trace buffer.
1587 //    It posts a task when it's half full and expects something outside of
1588 //    base/ to drain the ring-buffer and serialize it, eventually writing it
1589 //    into the trace itself, before it gets 100% full.
1590 //
1591 // 2. A class in tracing/core which takes care of serializing the meta-trace
1592 //    buffer into the trace using a TraceWriter. See metatrace_writer.h .
1593 //
1594 // 3. A data source in traced_probes that, when be enabled via the trace config,
1595 //    injects metatrace events into the trace. See metatrace_data_source.h .
1596 //
1597 // The available events and tags are defined in metatrace_events.h .
1598 
1599 namespace perfetto {
1600 
1601 namespace base {
1602 class TaskRunner;
1603 }  // namespace base
1604 
1605 namespace metatrace {
1606 
1607 // Meta-tracing is organized in "tags" that can be selectively enabled. This is
1608 // to enable meta-tracing only of one sub-system. This word has one "enabled"
1609 // bit for each tag. 0 -> meta-tracing off.
1610 extern std::atomic<uint32_t> g_enabled_tags;
1611 
1612 // Time of the Enable() call. Used as a reference for keeping delta timestmaps
1613 // in Record.
1614 extern std::atomic<uint64_t> g_enabled_timestamp;
1615 
1616 // Enables meta-tracing for one or more tags. Once enabled it will discard any
1617 // further Enable() calls and return false until disabled,
1618 // |read_task| is a closure that will be called enqueued |task_runner| when the
1619 // meta-tracing ring buffer is half full. The task is expected to read the ring
1620 // buffer using RingBuffer::GetReadIterator() and serialize the contents onto a
1621 // file or into the trace itself.
1622 // Must be called on the |task_runner| passed.
1623 // |task_runner| must have static lifetime.
1624 bool Enable(std::function<void()> read_task, base::TaskRunner*, uint32_t tags);
1625 
1626 // Disables meta-tracing.
1627 // Must be called on the same |task_runner| as Enable().
1628 void Disable();
1629 
TraceTimeNowNs()1630 inline uint64_t TraceTimeNowNs() {
1631   return static_cast<uint64_t>(base::GetBootTimeNs().count());
1632 }
1633 
1634 // Returns a relaxed view of whether metatracing is enabled for the given tag.
1635 // Useful for skipping unnecessary argument computation if metatracing is off.
IsEnabled(uint32_t tag)1636 inline bool IsEnabled(uint32_t tag) {
1637   auto enabled_tags = g_enabled_tags.load(std::memory_order_relaxed);
1638   return PERFETTO_UNLIKELY((enabled_tags & tag) != 0);
1639 }
1640 
1641 // Holds the data for a metatrace event or counter.
1642 struct Record {
1643   static constexpr uint16_t kTypeMask = 0x8000;
1644   static constexpr uint16_t kTypeCounter = 0x8000;
1645   static constexpr uint16_t kTypeEvent = 0;
1646 
timestamp_nsperfetto::metatrace::Record1647   uint64_t timestamp_ns() const {
1648     auto base_ns = g_enabled_timestamp.load(std::memory_order_relaxed);
1649     PERFETTO_DCHECK(base_ns);
1650     return base_ns + ((static_cast<uint64_t>(timestamp_ns_high) << 32) |
1651                       timestamp_ns_low);
1652   }
1653 
set_timestampperfetto::metatrace::Record1654   void set_timestamp(uint64_t ts) {
1655     auto t_start = g_enabled_timestamp.load(std::memory_order_relaxed);
1656     uint64_t diff = ts - t_start;
1657     PERFETTO_DCHECK(diff < (1ull << 48));
1658     timestamp_ns_low = static_cast<uint32_t>(diff);
1659     timestamp_ns_high = static_cast<uint16_t>(diff >> 32);
1660   }
1661 
1662   // We can't just memset() this class because on MSVC std::atomic<> is not
1663   // trivially constructible anymore. Also std::atomic<> has a deleted copy
1664   // constructor so we cant just do "*this = Record()" either.
1665   // See http://bit.ly/339Jlzd .
clearperfetto::metatrace::Record1666   void clear() {
1667     this->~Record();
1668     new (this) Record();
1669   }
1670 
1671   // This field holds the type (counter vs event) in the MSB and event ID (as
1672   // defined in metatrace_events.h) in the lowest 15 bits. It is also used also
1673   // as a linearization point: this is always written after all the other
1674   // fields with a release-store. This is so the reader can determine whether it
1675   // can safely process the other event fields after a load-acquire.
1676   std::atomic<uint16_t> type_and_id{};
1677 
1678   // Timestamp is stored as a 48-bits value diffed against g_enabled_timestamp.
1679   // This gives us 78 hours from Enabled().
1680   uint16_t timestamp_ns_high = 0;
1681   uint32_t timestamp_ns_low = 0;
1682 
1683   uint32_t thread_id = 0;
1684 
1685   union {
1686     // Only one of the two elements can be zero initialized, clang complains
1687     // about "initializing multiple members of union" otherwise.
1688     uint32_t duration_ns = 0;  // If type == event.
1689     int32_t counter_value;     // If type == counter.
1690   };
1691 };
1692 
1693 // Hold the meta-tracing data into a statically allocated array.
1694 // This class uses static storage (as opposite to being a singleton) to:
1695 // - Have the guarantee of always valid storage, so that meta-tracing can be
1696 //   safely used in any part of the codebase, including base/ itself.
1697 // - Avoid barriers that thread-safe static locals would require.
1698 class RingBuffer {
1699  public:
1700   static constexpr size_t kCapacity = 4096;  // 4096 * 16 bytes = 64K.
1701 
1702   // This iterator is not idempotent and will bump the read index in the buffer
1703   // at the end of the reads. There can be only one reader at any time.
1704   // Usage: for (auto it = RingBuffer::GetReadIterator(); it; ++it) { it->... }
1705   class ReadIterator {
1706    public:
ReadIterator(ReadIterator && other)1707     ReadIterator(ReadIterator&& other) {
1708       PERFETTO_DCHECK(other.valid_);
1709       cur_ = other.cur_;
1710       end_ = other.end_;
1711       valid_ = other.valid_;
1712       other.valid_ = false;
1713     }
1714 
~ReadIterator()1715     ~ReadIterator() {
1716       if (!valid_)
1717         return;
1718       PERFETTO_DCHECK(cur_ >= RingBuffer::rd_index_);
1719       PERFETTO_DCHECK(cur_ <= RingBuffer::wr_index_);
1720       RingBuffer::rd_index_.store(cur_, std::memory_order_release);
1721     }
1722 
operator bool() const1723     explicit operator bool() const { return cur_ < end_; }
operator ->() const1724     const Record* operator->() const { return RingBuffer::At(cur_); }
operator *() const1725     const Record& operator*() const { return *operator->(); }
1726 
1727     // This is for ++it. it++ is deliberately not supported.
operator ++()1728     ReadIterator& operator++() {
1729       PERFETTO_DCHECK(cur_ < end_);
1730       // Once a record has been read, mark it as free clearing its type_and_id,
1731       // so if we encounter it in another read iteration while being written
1732       // we know it's not fully written yet.
1733       // The memory_order_relaxed below is enough because:
1734       // - The reader is single-threaded and doesn't re-read the same records.
1735       // - Before starting a read batch, the reader has an acquire barrier on
1736       //   |rd_index_|.
1737       // - After terminating a read batch, the ~ReadIterator dtor updates the
1738       //   |rd_index_| with a release-store.
1739       // - Reader and writer are typically kCapacity/2 apart. So unless an
1740       //   overrun happens a writer won't reuse a newly released record any time
1741       //   soon. If an overrun happens, everything is busted regardless.
1742       At(cur_)->type_and_id.store(0, std::memory_order_relaxed);
1743       ++cur_;
1744       return *this;
1745     }
1746 
1747    private:
1748     friend class RingBuffer;
ReadIterator(uint64_t begin,uint64_t end)1749     ReadIterator(uint64_t begin, uint64_t end)
1750         : cur_(begin), end_(end), valid_(true) {}
1751     ReadIterator& operator=(const ReadIterator&) = delete;
1752     ReadIterator(const ReadIterator&) = delete;
1753 
1754     uint64_t cur_;
1755     uint64_t end_;
1756     bool valid_;
1757   };
1758 
At(uint64_t index)1759   static Record* At(uint64_t index) {
1760     // Doesn't really have to be pow2, but if not the compiler will emit
1761     // arithmetic operations to compute the modulo instead of a bitwise AND.
1762     static_assert(!(kCapacity & (kCapacity - 1)), "kCapacity must be pow2");
1763     PERFETTO_DCHECK(index >= rd_index_);
1764     PERFETTO_DCHECK(index <= wr_index_);
1765     return &records_[index % kCapacity];
1766   }
1767 
1768   // Must be called on the same task runner passed to Enable()
GetReadIterator()1769   static ReadIterator GetReadIterator() {
1770     PERFETTO_DCHECK(RingBuffer::IsOnValidTaskRunner());
1771     return ReadIterator(rd_index_.load(std::memory_order_acquire),
1772                         wr_index_.load(std::memory_order_acquire));
1773   }
1774 
1775   static Record* AppendNewRecord();
1776   static void Reset();
1777 
has_overruns()1778   static bool has_overruns() {
1779     return has_overruns_.load(std::memory_order_acquire);
1780   }
1781 
1782   // Can temporarily return a value >= kCapacity but is eventually consistent.
1783   // This would happen in case of overruns until threads hit the --wr_index_
1784   // in AppendNewRecord().
GetSizeForTesting()1785   static uint64_t GetSizeForTesting() {
1786     auto wr_index = wr_index_.load(std::memory_order_relaxed);
1787     auto rd_index = rd_index_.load(std::memory_order_relaxed);
1788     PERFETTO_DCHECK(wr_index >= rd_index);
1789     return wr_index - rd_index;
1790   }
1791 
1792  private:
1793   friend class ReadIterator;
1794 
1795   // Returns true if the caller is on the task runner passed to Enable().
1796   // Used only for DCHECKs.
1797   static bool IsOnValidTaskRunner();
1798 
1799   static std::array<Record, kCapacity> records_;
1800   static std::atomic<bool> read_task_queued_;
1801   static std::atomic<uint64_t> wr_index_;
1802   static std::atomic<uint64_t> rd_index_;
1803   static std::atomic<bool> has_overruns_;
1804   static Record bankruptcy_record_;  // Used in case of overruns.
1805 };
1806 
TraceCounter(uint32_t tag,uint16_t id,int32_t value)1807 inline void TraceCounter(uint32_t tag, uint16_t id, int32_t value) {
1808   // memory_order_relaxed is okay because the storage has static lifetime.
1809   // It is safe to accidentally log an event soon after disabling.
1810   auto enabled_tags = g_enabled_tags.load(std::memory_order_relaxed);
1811   if (PERFETTO_LIKELY((enabled_tags & tag) == 0))
1812     return;
1813   Record* record = RingBuffer::AppendNewRecord();
1814   record->thread_id = static_cast<uint32_t>(base::GetThreadId());
1815   record->set_timestamp(TraceTimeNowNs());
1816   record->counter_value = value;
1817   record->type_and_id.store(Record::kTypeCounter | id,
1818                             std::memory_order_release);
1819 }
1820 
1821 class ScopedEvent {
1822  public:
ScopedEvent(uint32_t tag,uint16_t event_id)1823   ScopedEvent(uint32_t tag, uint16_t event_id) {
1824     auto enabled_tags = g_enabled_tags.load(std::memory_order_relaxed);
1825     if (PERFETTO_LIKELY((enabled_tags & tag) == 0))
1826       return;
1827     event_id_ = event_id;
1828     record_ = RingBuffer::AppendNewRecord();
1829     record_->thread_id = static_cast<uint32_t>(base::GetThreadId());
1830     record_->set_timestamp(TraceTimeNowNs());
1831   }
1832 
~ScopedEvent()1833   ~ScopedEvent() {
1834     if (PERFETTO_LIKELY(!record_))
1835       return;
1836     auto now = TraceTimeNowNs();
1837     record_->duration_ns = static_cast<uint32_t>(now - record_->timestamp_ns());
1838     record_->type_and_id.store(Record::kTypeEvent | event_id_,
1839                                std::memory_order_release);
1840   }
1841 
1842  private:
1843   Record* record_ = nullptr;
1844   uint16_t event_id_ = 0;
1845   ScopedEvent(const ScopedEvent&) = delete;
1846   ScopedEvent& operator=(const ScopedEvent&) = delete;
1847 };
1848 
1849 // Boilerplate to derive a unique variable name for the event.
1850 #define PERFETTO_METATRACE_UID2(a, b) a##b
1851 #define PERFETTO_METATRACE_UID(x) PERFETTO_METATRACE_UID2(metatrace_, x)
1852 
1853 #define PERFETTO_METATRACE_SCOPED(TAG, ID)                                \
1854   ::perfetto::metatrace::ScopedEvent PERFETTO_METATRACE_UID(__COUNTER__)( \
1855       ::perfetto::metatrace::TAG, ::perfetto::metatrace::ID)
1856 
1857 #define PERFETTO_METATRACE_COUNTER(TAG, ID, VALUE)                \
1858   ::perfetto::metatrace::TraceCounter(::perfetto::metatrace::TAG, \
1859                                       ::perfetto::metatrace::ID,  \
1860                                       static_cast<int32_t>(VALUE))
1861 
1862 }  // namespace metatrace
1863 }  // namespace perfetto
1864 
1865 #endif  // INCLUDE_PERFETTO_EXT_BASE_METATRACE_H_
1866 // gen_amalgamated begin header: include/perfetto/base/task_runner.h
1867 /*
1868  * Copyright (C) 2017 The Android Open Source Project
1869  *
1870  * Licensed under the Apache License, Version 2.0 (the "License");
1871  * you may not use this file except in compliance with the License.
1872  * You may obtain a copy of the License at
1873  *
1874  *      http://www.apache.org/licenses/LICENSE-2.0
1875  *
1876  * Unless required by applicable law or agreed to in writing, software
1877  * distributed under the License is distributed on an "AS IS" BASIS,
1878  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1879  * See the License for the specific language governing permissions and
1880  * limitations under the License.
1881  */
1882 
1883 #ifndef INCLUDE_PERFETTO_BASE_TASK_RUNNER_H_
1884 #define INCLUDE_PERFETTO_BASE_TASK_RUNNER_H_
1885 
1886 #include <stdint.h>
1887 
1888 #include <functional>
1889 
1890 // gen_amalgamated expanded: #include "perfetto/base/export.h"
1891 // gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
1892 
1893 namespace perfetto {
1894 namespace base {
1895 
1896 // A generic interface to allow the library clients to interleave the execution
1897 // of the tracing internals in their runtime environment.
1898 // The expectation is that all tasks, which are queued either via PostTask() or
1899 // AddFileDescriptorWatch(), are executed on the same sequence (either on the
1900 // same thread, or on a thread pool that gives sequencing guarantees).
1901 //
1902 // Tasks are never executed synchronously inside PostTask and there is a full
1903 // memory barrier between tasks.
1904 //
1905 // All methods of this interface can be called from any thread.
1906 class PERFETTO_EXPORT TaskRunner {
1907  public:
1908   virtual ~TaskRunner();
1909 
1910   // Schedule a task for immediate execution. Immediate tasks are always
1911   // executed in the order they are posted. Can be called from any thread.
1912   virtual void PostTask(std::function<void()>) = 0;
1913 
1914   // Schedule a task for execution after |delay_ms|. Note that there is no
1915   // strict ordering guarantee between immediate and delayed tasks. Can be
1916   // called from any thread.
1917   virtual void PostDelayedTask(std::function<void()>, uint32_t delay_ms) = 0;
1918 
1919   // Schedule a task to run when the handle becomes readable. The same handle
1920   // can only be monitored by one function. Note that this function only needs
1921   // to be implemented on platforms where the built-in ipc framework is used.
1922   // Can be called from any thread.
1923   // TODO(skyostil): Refactor this out of the shared interface.
1924   virtual void AddFileDescriptorWatch(PlatformHandle,
1925                                       std::function<void()>) = 0;
1926 
1927   // Remove a previously scheduled watch for the handle. If this is run on the
1928   // target thread of this TaskRunner, guarantees that the task registered to
1929   // this handle will not be executed after this function call.
1930   // Can be called from any thread.
1931   virtual void RemoveFileDescriptorWatch(PlatformHandle) = 0;
1932 
1933   // Checks if the current thread is the same thread where the TaskRunner's task
1934   // run. This allows single threaded task runners (like the ones used in
1935   // perfetto) to inform the caller that anything posted will run on the same
1936   // thread/sequence. This can allow some callers to skip PostTask and instead
1937   // directly execute the code. Can be called from any thread.
1938   virtual bool RunsTasksOnCurrentThread() const = 0;
1939 };
1940 
1941 }  // namespace base
1942 }  // namespace perfetto
1943 
1944 #endif  // INCLUDE_PERFETTO_BASE_TASK_RUNNER_H_
1945 // gen_amalgamated begin header: include/perfetto/ext/base/thread_annotations.h
1946 /*
1947  * Copyright (C) 2019 The Android Open Source Project
1948  *
1949  * Licensed under the Apache License, Version 2.0 (the "License");
1950  * you may not use this file except in compliance with the License.
1951  * You may obtain a copy of the License at
1952  *
1953  *      http://www.apache.org/licenses/LICENSE-2.0
1954  *
1955  * Unless required by applicable law or agreed to in writing, software
1956  * distributed under the License is distributed on an "AS IS" BASIS,
1957  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1958  * See the License for the specific language governing permissions and
1959  * limitations under the License.
1960  */
1961 
1962 #ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_ANNOTATIONS_H_
1963 #define INCLUDE_PERFETTO_EXT_BASE_THREAD_ANNOTATIONS_H_
1964 
1965 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
1966 
1967 // Windows TSAN doesn't currently support these annotations.
1968 #if defined(THREAD_SANITIZER) && !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1969 extern "C" {
1970 void AnnotateBenignRaceSized(const char* file,
1971                              int line,
1972                              unsigned long address,
1973                              unsigned long size,
1974                              const char* description);
1975 }
1976 
1977 #define PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(pointer, size, description)   \
1978   AnnotateBenignRaceSized(__FILE__, __LINE__,                             \
1979                           reinterpret_cast<unsigned long>(pointer), size, \
1980                           description);
1981 #else  // defined(ADDRESS_SANITIZER)
1982 #define PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(pointer, size, description)
1983 #endif  // defined(ADDRESS_SANITIZER)
1984 
1985 #endif  // INCLUDE_PERFETTO_EXT_BASE_THREAD_ANNOTATIONS_H_
1986 /*
1987  * Copyright (C) 2018 The Android Open Source Project
1988  *
1989  * Licensed under the Apache License, Version 2.0 (the "License");
1990  * you may not use this file except in compliance with the License.
1991  * You may obtain a copy of the License at
1992  *
1993  *      http://www.apache.org/licenses/LICENSE-2.0
1994  *
1995  * Unless required by applicable law or agreed to in writing, software
1996  * distributed under the License is distributed on an "AS IS" BASIS,
1997  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1998  * See the License for the specific language governing permissions and
1999  * limitations under the License.
2000  */
2001 
2002 // gen_amalgamated expanded: #include "perfetto/ext/base/metatrace.h"
2003 
2004 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
2005 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
2006 // gen_amalgamated expanded: #include "perfetto/base/time.h"
2007 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
2008 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_annotations.h"
2009 
2010 namespace perfetto {
2011 namespace metatrace {
2012 
2013 std::atomic<uint32_t> g_enabled_tags{0};
2014 std::atomic<uint64_t> g_enabled_timestamp{0};
2015 
2016 // static members
2017 constexpr size_t RingBuffer::kCapacity;
2018 std::array<Record, RingBuffer::kCapacity> RingBuffer::records_;
2019 std::atomic<bool> RingBuffer::read_task_queued_;
2020 std::atomic<uint64_t> RingBuffer::wr_index_;
2021 std::atomic<uint64_t> RingBuffer::rd_index_;
2022 std::atomic<bool> RingBuffer::has_overruns_;
2023 Record RingBuffer::bankruptcy_record_;
2024 
2025 constexpr uint16_t Record::kTypeMask;
2026 constexpr uint16_t Record::kTypeCounter;
2027 constexpr uint16_t Record::kTypeEvent;
2028 
2029 namespace {
2030 
2031 // std::function<> is not trivially de/constructible. This struct wraps it in a
2032 // heap-allocated struct to avoid static initializers.
2033 struct Delegate {
GetInstanceperfetto::metatrace::__anon2fbee8800911::Delegate2034   static Delegate* GetInstance() {
2035     static Delegate* instance = new Delegate();
2036     return instance;
2037   }
2038 
2039   base::TaskRunner* task_runner = nullptr;
2040   std::function<void()> read_task;
2041 };
2042 
2043 }  // namespace
2044 
Enable(std::function<void ()> read_task,base::TaskRunner * task_runner,uint32_t tags)2045 bool Enable(std::function<void()> read_task,
2046             base::TaskRunner* task_runner,
2047             uint32_t tags) {
2048   PERFETTO_DCHECK(read_task);
2049   PERFETTO_DCHECK(task_runner->RunsTasksOnCurrentThread());
2050   if (g_enabled_tags.load(std::memory_order_acquire))
2051     return false;
2052 
2053   Delegate* dg = Delegate::GetInstance();
2054   dg->task_runner = task_runner;
2055   dg->read_task = std::move(read_task);
2056   RingBuffer::Reset();
2057   g_enabled_timestamp.store(TraceTimeNowNs(), std::memory_order_relaxed);
2058   g_enabled_tags.store(tags, std::memory_order_release);
2059   return true;
2060 }
2061 
Disable()2062 void Disable() {
2063   g_enabled_tags.store(0, std::memory_order_release);
2064   Delegate* dg = Delegate::GetInstance();
2065   PERFETTO_DCHECK(!dg->task_runner ||
2066                   dg->task_runner->RunsTasksOnCurrentThread());
2067   dg->task_runner = nullptr;
2068   dg->read_task = nullptr;
2069 }
2070 
2071 // static
Reset()2072 void RingBuffer::Reset() {
2073   bankruptcy_record_.clear();
2074   for (Record& record : records_)
2075     record.clear();
2076   wr_index_ = 0;
2077   rd_index_ = 0;
2078   has_overruns_ = false;
2079   read_task_queued_ = false;
2080 }
2081 
2082 // static
AppendNewRecord()2083 Record* RingBuffer::AppendNewRecord() {
2084   auto wr_index = wr_index_.fetch_add(1, std::memory_order_acq_rel);
2085 
2086   // rd_index can only monotonically increase, we don't care if we read an
2087   // older value, we'll just hit the slow-path a bit earlier if it happens.
2088   auto rd_index = rd_index_.load(std::memory_order_relaxed);
2089 
2090   PERFETTO_DCHECK(wr_index >= rd_index);
2091   auto size = wr_index - rd_index;
2092   if (PERFETTO_LIKELY(size < kCapacity / 2))
2093     return At(wr_index);
2094 
2095   // Slow-path: Enqueue the read task and handle overruns.
2096   bool expected = false;
2097   if (RingBuffer::read_task_queued_.compare_exchange_strong(expected, true)) {
2098     Delegate* dg = Delegate::GetInstance();
2099     if (dg->task_runner) {
2100       dg->task_runner->PostTask([] {
2101         // Meta-tracing might have been disabled in the meantime.
2102         auto read_task = Delegate::GetInstance()->read_task;
2103         if (read_task)
2104           read_task();
2105         RingBuffer::read_task_queued_ = false;
2106       });
2107     }
2108   }
2109 
2110   if (PERFETTO_LIKELY(size < kCapacity))
2111     return At(wr_index);
2112 
2113   has_overruns_.store(true, std::memory_order_release);
2114   wr_index_.fetch_sub(1, std::memory_order_acq_rel);
2115 
2116   // In the case of overflows, threads will race writing on the same memory
2117   // location and TSan will rightly complain. This is fine though because nobody
2118   // will read the bankruptcy record and it's designed to contain garbage.
2119   PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(&bankruptcy_record_, sizeof(Record),
2120                                       "nothing reads bankruptcy_record_")
2121   return &bankruptcy_record_;
2122 }
2123 
2124 // static
IsOnValidTaskRunner()2125 bool RingBuffer::IsOnValidTaskRunner() {
2126   auto* task_runner = Delegate::GetInstance()->task_runner;
2127   return task_runner && task_runner->RunsTasksOnCurrentThread();
2128 }
2129 
2130 }  // namespace metatrace
2131 }  // namespace perfetto
2132 // gen_amalgamated begin source: src/base/paged_memory.cc
2133 // gen_amalgamated begin header: include/perfetto/ext/base/paged_memory.h
2134 // gen_amalgamated begin header: include/perfetto/ext/base/container_annotations.h
2135 /*
2136  * Copyright (C) 2018 The Android Open Source Project
2137  *
2138  * Licensed under the Apache License, Version 2.0 (the "License");
2139  * you may not use this file except in compliance with the License.
2140  * You may obtain a copy of the License at
2141  *
2142  *      http://www.apache.org/licenses/LICENSE-2.0
2143  *
2144  * Unless required by applicable law or agreed to in writing, software
2145  * distributed under the License is distributed on an "AS IS" BASIS,
2146  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2147  * See the License for the specific language governing permissions and
2148  * limitations under the License.
2149  */
2150 
2151 #ifndef INCLUDE_PERFETTO_EXT_BASE_CONTAINER_ANNOTATIONS_H_
2152 #define INCLUDE_PERFETTO_EXT_BASE_CONTAINER_ANNOTATIONS_H_
2153 
2154 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
2155 
2156 // Windows ASAN doesn't currently support these annotations.
2157 #if defined(ADDRESS_SANITIZER) && !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
2158     !defined(ADDRESS_SANITIZER_WITHOUT_INSTRUMENTATION)
2159 
2160 #define ANNOTATE_NEW_BUFFER(buffer, capacity, new_size)                      \
2161   if (buffer) {                                                              \
2162     __sanitizer_annotate_contiguous_container(buffer, (buffer) + (capacity), \
2163                                               (buffer) + (capacity),         \
2164                                               (buffer) + (new_size));        \
2165   }
2166 #define ANNOTATE_DELETE_BUFFER(buffer, capacity, old_size)                   \
2167   if (buffer) {                                                              \
2168     __sanitizer_annotate_contiguous_container(buffer, (buffer) + (capacity), \
2169                                               (buffer) + (old_size),         \
2170                                               (buffer) + (capacity));        \
2171   }
2172 #define ANNOTATE_CHANGE_SIZE(buffer, capacity, old_size, new_size)           \
2173   if (buffer) {                                                              \
2174     __sanitizer_annotate_contiguous_container(buffer, (buffer) + (capacity), \
2175                                               (buffer) + (old_size),         \
2176                                               (buffer) + (new_size));        \
2177   }
2178 #define ANNOTATE_CHANGE_CAPACITY(buffer, old_capacity, buffer_size, \
2179                                  new_capacity)                      \
2180   ANNOTATE_DELETE_BUFFER(buffer, old_capacity, buffer_size);        \
2181   ANNOTATE_NEW_BUFFER(buffer, new_capacity, buffer_size);
2182 // Annotations require buffers to begin on an 8-byte boundary.
2183 #else  // defined(ADDRESS_SANITIZER)
2184 #define ANNOTATE_NEW_BUFFER(buffer, capacity, new_size)
2185 #define ANNOTATE_DELETE_BUFFER(buffer, capacity, old_size)
2186 #define ANNOTATE_CHANGE_SIZE(buffer, capacity, old_size, new_size)
2187 #define ANNOTATE_CHANGE_CAPACITY(buffer, old_capacity, buffer_size, \
2188                                  new_capacity)
2189 #endif  // defined(ADDRESS_SANITIZER)
2190 
2191 #endif  // INCLUDE_PERFETTO_EXT_BASE_CONTAINER_ANNOTATIONS_H_
2192 /*
2193  * Copyright (C) 2017 The Android Open Source Project
2194  *
2195  * Licensed under the Apache License, Version 2.0 (the "License");
2196  * you may not use this file except in compliance with the License.
2197  * You may obtain a copy of the License at
2198  *
2199  *      http://www.apache.org/licenses/LICENSE-2.0
2200  *
2201  * Unless required by applicable law or agreed to in writing, software
2202  * distributed under the License is distributed on an "AS IS" BASIS,
2203  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2204  * See the License for the specific language governing permissions and
2205  * limitations under the License.
2206  */
2207 
2208 #ifndef INCLUDE_PERFETTO_EXT_BASE_PAGED_MEMORY_H_
2209 #define INCLUDE_PERFETTO_EXT_BASE_PAGED_MEMORY_H_
2210 
2211 #include <memory>
2212 
2213 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
2214 // gen_amalgamated expanded: #include "perfetto/ext/base/container_annotations.h"
2215 
2216 // We need to track the committed size on windows and when ASAN is enabled.
2217 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) || defined(ADDRESS_SANITIZER)
2218 #define TRACK_COMMITTED_SIZE() 1
2219 #else
2220 #define TRACK_COMMITTED_SIZE() 0
2221 #endif
2222 
2223 namespace perfetto {
2224 namespace base {
2225 
2226 class PagedMemory {
2227  public:
2228   // Initializes an invalid PagedMemory pointing to nullptr.
2229   PagedMemory();
2230 
2231   ~PagedMemory();
2232 
2233   PagedMemory(PagedMemory&& other) noexcept;
2234   PagedMemory& operator=(PagedMemory&& other);
2235 
2236   enum AllocationFlags {
2237     // By default, Allocate() crashes if the underlying mmap fails (e.g., if out
2238     // of virtual address space). When this flag is provided, an invalid
2239     // PagedMemory pointing to nullptr is returned in this case instead.
2240     kMayFail = 1 << 0,
2241 
2242     // By default, Allocate() commits the allocated memory immediately. When
2243     // this flag is provided, the memory virtual address space may only be
2244     // reserved and the user should call EnsureCommitted() before writing to
2245     // memory addresses.
2246     kDontCommit = 1 << 1,
2247   };
2248 
2249   // Allocates |size| bytes using mmap(MAP_ANONYMOUS). The returned memory is
2250   // guaranteed to be page-aligned and guaranteed to be zeroed.
2251   // For |flags|, see the AllocationFlags enum above.
2252   static PagedMemory Allocate(size_t size, int flags = 0);
2253 
2254   // Hint to the OS that the memory range is not needed and can be discarded.
2255   // The memory remains accessible and its contents may be retained, or they
2256   // may be zeroed. This function may be a NOP on some platforms. Returns true
2257   // if implemented.
2258   bool AdviseDontNeed(void* p, size_t size);
2259 
2260   // Ensures that at least the first |committed_size| bytes of the allocated
2261   // memory region are committed. The implementation may commit memory in larger
2262   // chunks above |committed_size|. Crashes if the memory couldn't be committed.
2263 #if TRACK_COMMITTED_SIZE()
2264   void EnsureCommitted(size_t committed_size);
2265 #else   // TRACK_COMMITTED_SIZE()
EnsureCommitted(size_t)2266   void EnsureCommitted(size_t /*committed_size*/) {}
2267 #endif  // TRACK_COMMITTED_SIZE()
2268 
Get() const2269   inline void* Get() const noexcept { return p_; }
IsValid() const2270   inline bool IsValid() const noexcept { return !!p_; }
size() const2271   inline size_t size() const noexcept { return size_; }
2272 
2273  private:
2274   PagedMemory(char* p, size_t size);
2275 
2276   PagedMemory(const PagedMemory&) = delete;
2277   // Defaulted for implementation of move constructor + assignment.
2278   PagedMemory& operator=(const PagedMemory&) = default;
2279 
2280   char* p_ = nullptr;
2281 
2282   // The size originally passed to Allocate(). The actual virtual memory
2283   // reservation will be larger due to: (i) guard pages; (ii) rounding up to
2284   // the system page size.
2285   size_t size_ = 0;
2286 
2287 #if TRACK_COMMITTED_SIZE()
2288   size_t committed_size_ = 0u;
2289 #endif  // TRACK_COMMITTED_SIZE()
2290 };
2291 
2292 }  // namespace base
2293 }  // namespace perfetto
2294 
2295 #endif  // INCLUDE_PERFETTO_EXT_BASE_PAGED_MEMORY_H_
2296 /*
2297  * Copyright (C) 2017 The Android Open Source Project
2298  *
2299  * Licensed under the Apache License, Version 2.0 (the "License");
2300  * you may not use this file except in compliance with the License.
2301  * You may obtain a copy of the License at
2302  *
2303  *      http://www.apache.org/licenses/LICENSE-2.0
2304  *
2305  * Unless required by applicable law or agreed to in writing, software
2306  * distributed under the License is distributed on an "AS IS" BASIS,
2307  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2308  * See the License for the specific language governing permissions and
2309  * limitations under the License.
2310  */
2311 
2312 // gen_amalgamated expanded: #include "perfetto/ext/base/paged_memory.h"
2313 
2314 #include <algorithm>
2315 #include <cmath>
2316 
2317 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2318 #include <Windows.h>
2319 #else  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2320 #include <sys/mman.h>
2321 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2322 
2323 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
2324 // gen_amalgamated expanded: #include "perfetto/ext/base/container_annotations.h"
2325 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
2326 
2327 namespace perfetto {
2328 namespace base {
2329 
2330 namespace {
2331 
2332 #if TRACK_COMMITTED_SIZE()
2333 constexpr size_t kCommitChunkSize = 4 * 1024 * 1024;  // 4MB
2334 #endif
2335 
RoundUpToSysPageSize(size_t req_size)2336 size_t RoundUpToSysPageSize(size_t req_size) {
2337   const size_t page_size = GetSysPageSize();
2338   return (req_size + page_size - 1) & ~(page_size - 1);
2339 }
2340 
GuardSize()2341 size_t GuardSize() {
2342   return GetSysPageSize();
2343 }
2344 
2345 }  // namespace
2346 
2347 // static
Allocate(size_t req_size,int flags)2348 PagedMemory PagedMemory::Allocate(size_t req_size, int flags) {
2349   size_t rounded_up_size = RoundUpToSysPageSize(req_size);
2350   PERFETTO_CHECK(rounded_up_size >= req_size);
2351   size_t outer_size = rounded_up_size + GuardSize() * 2;
2352 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2353   void* ptr = VirtualAlloc(nullptr, outer_size, MEM_RESERVE, PAGE_NOACCESS);
2354   if (!ptr && (flags & kMayFail))
2355     return PagedMemory();
2356   PERFETTO_CHECK(ptr);
2357   char* usable_region = reinterpret_cast<char*>(ptr) + GuardSize();
2358 #else   // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2359   void* ptr = mmap(nullptr, outer_size, PROT_READ | PROT_WRITE,
2360                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
2361   if (ptr == MAP_FAILED && (flags & kMayFail))
2362     return PagedMemory();
2363   PERFETTO_CHECK(ptr && ptr != MAP_FAILED);
2364   char* usable_region = reinterpret_cast<char*>(ptr) + GuardSize();
2365   int res = mprotect(ptr, GuardSize(), PROT_NONE);
2366   res |= mprotect(usable_region + rounded_up_size, GuardSize(), PROT_NONE);
2367   PERFETTO_CHECK(res == 0);
2368 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2369 
2370   auto memory = PagedMemory(usable_region, req_size);
2371 #if TRACK_COMMITTED_SIZE()
2372   size_t initial_commit = req_size;
2373   if (flags & kDontCommit)
2374     initial_commit = std::min(initial_commit, kCommitChunkSize);
2375   memory.EnsureCommitted(initial_commit);
2376 #endif  // TRACK_COMMITTED_SIZE()
2377   return memory;
2378 }
2379 
PagedMemory()2380 PagedMemory::PagedMemory() {}
2381 
2382 // clang-format off
PagedMemory(char * p,size_t size)2383 PagedMemory::PagedMemory(char* p, size_t size) : p_(p), size_(size) {
2384   ANNOTATE_NEW_BUFFER(p_, size_, committed_size_)
2385 }
2386 
PagedMemory(PagedMemory && other)2387 PagedMemory::PagedMemory(PagedMemory&& other) noexcept {
2388   *this = other;
2389   other.p_ = nullptr;
2390 }
2391 // clang-format on
2392 
operator =(PagedMemory && other)2393 PagedMemory& PagedMemory::operator=(PagedMemory&& other) {
2394   this->~PagedMemory();
2395   new (this) PagedMemory(std::move(other));
2396   return *this;
2397 }
2398 
~PagedMemory()2399 PagedMemory::~PagedMemory() {
2400   if (!p_)
2401     return;
2402   PERFETTO_CHECK(size_);
2403   char* start = p_ - GuardSize();
2404 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2405   BOOL res = VirtualFree(start, 0, MEM_RELEASE);
2406   PERFETTO_CHECK(res != 0);
2407 #else   // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2408   const size_t outer_size = RoundUpToSysPageSize(size_) + GuardSize() * 2;
2409   int res = munmap(start, outer_size);
2410   PERFETTO_CHECK(res == 0);
2411 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2412   ANNOTATE_DELETE_BUFFER(p_, size_, committed_size_)
2413 }
2414 
AdviseDontNeed(void * p,size_t size)2415 bool PagedMemory::AdviseDontNeed(void* p, size_t size) {
2416   PERFETTO_DCHECK(p_);
2417   PERFETTO_DCHECK(p >= p_);
2418   PERFETTO_DCHECK(static_cast<char*>(p) + size <= p_ + size_);
2419 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) || PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
2420   // Discarding pages on Windows has more CPU cost than is justified for the
2421   // possible memory savings.
2422   return false;
2423 #else   // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) ||
2424         // PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
2425   // http://man7.org/linux/man-pages/man2/madvise.2.html
2426   int res = madvise(p, size, MADV_DONTNEED);
2427   PERFETTO_DCHECK(res == 0);
2428   return true;
2429 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) ||
2430         // PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
2431 }
2432 
2433 #if TRACK_COMMITTED_SIZE()
EnsureCommitted(size_t committed_size)2434 void PagedMemory::EnsureCommitted(size_t committed_size) {
2435   PERFETTO_DCHECK(committed_size > 0u);
2436   PERFETTO_DCHECK(committed_size <= size_);
2437 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2438   if (committed_size_ >= committed_size)
2439     return;
2440   // Rounding up.
2441   size_t delta = committed_size - committed_size_;
2442   size_t num_additional_chunks =
2443       (delta + kCommitChunkSize - 1) / kCommitChunkSize;
2444   PERFETTO_DCHECK(num_additional_chunks * kCommitChunkSize >= delta);
2445   // Don't commit more than the total size.
2446   size_t commit_size = std::min(num_additional_chunks * kCommitChunkSize,
2447                                 size_ - committed_size_);
2448   void* res = VirtualAlloc(p_ + committed_size_, commit_size, MEM_COMMIT,
2449                            PAGE_READWRITE);
2450   PERFETTO_CHECK(res);
2451   ANNOTATE_CHANGE_SIZE(p_, size_, committed_size_,
2452                        committed_size_ + commit_size)
2453   committed_size_ += commit_size;
2454 #else   // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2455   // mmap commits automatically as needed, so we only track here for ASAN.
2456   committed_size = std::max(committed_size_, committed_size);
2457   ANNOTATE_CHANGE_SIZE(p_, size_, committed_size_, committed_size)
2458   committed_size_ = committed_size;
2459 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2460 }
2461 #endif  // TRACK_COMMITTED_SIZE()
2462 
2463 }  // namespace base
2464 }  // namespace perfetto
2465 // gen_amalgamated begin source: src/base/periodic_task.cc
2466 // gen_amalgamated begin header: include/perfetto/ext/base/periodic_task.h
2467 // gen_amalgamated begin header: include/perfetto/ext/base/thread_checker.h
2468 /*
2469  * Copyright (C) 2017 The Android Open Source Project
2470  *
2471  * Licensed under the Apache License, Version 2.0 (the "License");
2472  * you may not use this file except in compliance with the License.
2473  * You may obtain a copy of the License at
2474  *
2475  *      http://www.apache.org/licenses/LICENSE-2.0
2476  *
2477  * Unless required by applicable law or agreed to in writing, software
2478  * distributed under the License is distributed on an "AS IS" BASIS,
2479  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2480  * See the License for the specific language governing permissions and
2481  * limitations under the License.
2482  */
2483 
2484 #ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_CHECKER_H_
2485 #define INCLUDE_PERFETTO_EXT_BASE_THREAD_CHECKER_H_
2486 
2487 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
2488 
2489 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2490 #include <pthread.h>
2491 #endif
2492 #include <atomic>
2493 
2494 // gen_amalgamated expanded: #include "perfetto/base/export.h"
2495 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
2496 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
2497 
2498 namespace perfetto {
2499 namespace base {
2500 
2501 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2502 using ThreadID = unsigned long;
2503 #else
2504 using ThreadID = pthread_t;
2505 #endif
2506 
2507 class PERFETTO_EXPORT ThreadChecker {
2508  public:
2509   ThreadChecker();
2510   ~ThreadChecker();
2511   ThreadChecker(const ThreadChecker&);
2512   ThreadChecker& operator=(const ThreadChecker&);
2513   bool CalledOnValidThread() const PERFETTO_WARN_UNUSED_RESULT;
2514   void DetachFromThread();
2515 
2516  private:
2517   mutable std::atomic<ThreadID> thread_id_;
2518 };
2519 
2520 #if PERFETTO_DCHECK_IS_ON() && !PERFETTO_BUILDFLAG(PERFETTO_CHROMIUM_BUILD)
2521 // TODO(primiano) Use Chromium's thread checker in Chromium.
2522 #define PERFETTO_THREAD_CHECKER(name) base::ThreadChecker name;
2523 #define PERFETTO_DCHECK_THREAD(name) \
2524   PERFETTO_DCHECK((name).CalledOnValidThread())
2525 #define PERFETTO_DETACH_FROM_THREAD(name) (name).DetachFromThread()
2526 #else
2527 #define PERFETTO_THREAD_CHECKER(name)
2528 #define PERFETTO_DCHECK_THREAD(name)
2529 #define PERFETTO_DETACH_FROM_THREAD(name)
2530 #endif  // PERFETTO_DCHECK_IS_ON()
2531 
2532 }  // namespace base
2533 }  // namespace perfetto
2534 
2535 #endif  // INCLUDE_PERFETTO_EXT_BASE_THREAD_CHECKER_H_
2536 // gen_amalgamated begin header: include/perfetto/ext/base/weak_ptr.h
2537 /*
2538  * Copyright (C) 2017 The Android Open Source Project
2539  *
2540  * Licensed under the Apache License, Version 2.0 (the "License");
2541  * you may not use this file except in compliance with the License.
2542  * You may obtain a copy of the License at
2543  *
2544  *      http://www.apache.org/licenses/LICENSE-2.0
2545  *
2546  * Unless required by applicable law or agreed to in writing, software
2547  * distributed under the License is distributed on an "AS IS" BASIS,
2548  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2549  * See the License for the specific language governing permissions and
2550  * limitations under the License.
2551  */
2552 
2553 #ifndef INCLUDE_PERFETTO_EXT_BASE_WEAK_PTR_H_
2554 #define INCLUDE_PERFETTO_EXT_BASE_WEAK_PTR_H_
2555 
2556 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
2557 
2558 #include <memory>
2559 
2560 namespace perfetto {
2561 namespace base {
2562 
2563 // A simple WeakPtr for single-threaded cases.
2564 // Generally keep the WeakPtrFactory as last fields in classes: it makes the
2565 // WeakPtr(s) invalidate as first thing in the class dtor.
2566 // Usage:
2567 // class MyClass {
2568 //  MyClass() : weak_factory_(this) {}
2569 //  WeakPtr<MyClass> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
2570 //
2571 // private:
2572 //  WeakPtrFactory<MyClass> weak_factory_;
2573 // }
2574 //
2575 // int main() {
2576 //  std::unique_ptr<MyClass> foo(new MyClass);
2577 //  auto wptr = foo.GetWeakPtr();
2578 //  ASSERT_TRUE(wptr);
2579 //  ASSERT_EQ(foo.get(), wptr->get());
2580 //  foo.reset();
2581 //  ASSERT_FALSE(wptr);
2582 //  ASSERT_EQ(nullptr, wptr->get());
2583 // }
2584 
2585 template <typename T>
2586 class WeakPtrFactory;  // Forward declaration, defined below.
2587 
2588 template <typename T>
2589 class WeakPtr {
2590  public:
WeakPtr()2591   WeakPtr() {}
2592   WeakPtr(const WeakPtr&) = default;
2593   WeakPtr& operator=(const WeakPtr&) = default;
2594   WeakPtr(WeakPtr&&) = default;
2595   WeakPtr& operator=(WeakPtr&&) = default;
2596 
get() const2597   T* get() const {
2598     PERFETTO_DCHECK_THREAD(thread_checker);
2599     return handle_ ? *handle_.get() : nullptr;
2600   }
operator ->() const2601   T* operator->() const { return get(); }
operator *() const2602   T& operator*() const { return *get(); }
2603 
operator bool() const2604   explicit operator bool() const { return !!get(); }
2605 
2606  private:
2607   friend class WeakPtrFactory<T>;
WeakPtr(const std::shared_ptr<T * > & handle)2608   explicit WeakPtr(const std::shared_ptr<T*>& handle) : handle_(handle) {}
2609 
2610   std::shared_ptr<T*> handle_;
2611   PERFETTO_THREAD_CHECKER(thread_checker)
2612 };
2613 
2614 template <typename T>
2615 class WeakPtrFactory {
2616  public:
WeakPtrFactory(T * owner)2617   explicit WeakPtrFactory(T* owner)
2618       : weak_ptr_(std::shared_ptr<T*>(new T* {owner})) {
2619     PERFETTO_DCHECK_THREAD(thread_checker);
2620   }
2621 
~WeakPtrFactory()2622   ~WeakPtrFactory() {
2623     PERFETTO_DCHECK_THREAD(thread_checker);
2624     *(weak_ptr_.handle_.get()) = nullptr;
2625   }
2626 
2627   // Can be safely called on any thread, since it simply copies |weak_ptr_|.
2628   // Note that any accesses to the returned pointer need to be made on the
2629   // thread that created/reset the factory.
GetWeakPtr() const2630   WeakPtr<T> GetWeakPtr() const { return weak_ptr_; }
2631 
2632   // Reset the factory to a new owner & thread. May only be called before any
2633   // weak pointers were passed out. Future weak pointers will be valid on the
2634   // calling thread.
Reset(T * owner)2635   void Reset(T* owner) {
2636     // Reset thread checker to current thread.
2637     PERFETTO_DETACH_FROM_THREAD(thread_checker);
2638     PERFETTO_DCHECK_THREAD(thread_checker);
2639 
2640     // We should not have passed out any weak pointers yet at this point.
2641     PERFETTO_DCHECK(weak_ptr_.handle_.use_count() == 1);
2642 
2643     weak_ptr_ = WeakPtr<T>(std::shared_ptr<T*>(new T* {owner}));
2644   }
2645 
2646  private:
2647   WeakPtrFactory(const WeakPtrFactory&) = delete;
2648   WeakPtrFactory& operator=(const WeakPtrFactory&) = delete;
2649 
2650   WeakPtr<T> weak_ptr_;
2651   PERFETTO_THREAD_CHECKER(thread_checker)
2652 };
2653 
2654 }  // namespace base
2655 }  // namespace perfetto
2656 
2657 #endif  // INCLUDE_PERFETTO_EXT_BASE_WEAK_PTR_H_
2658 /*
2659  * Copyright (C) 2021 The Android Open Source Project
2660  *
2661  * Licensed under the Apache License, Version 2.0 (the "License");
2662  * you may not use this file except in compliance with the License.
2663  * You may obtain a copy of the License at
2664  *
2665  *      http://www.apache.org/licenses/LICENSE-2.0
2666  *
2667  * Unless required by applicable law or agreed to in writing, software
2668  * distributed under the License is distributed on an "AS IS" BASIS,
2669  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2670  * See the License for the specific language governing permissions and
2671  * limitations under the License.
2672  */
2673 
2674 #ifndef INCLUDE_PERFETTO_EXT_BASE_PERIODIC_TASK_H_
2675 #define INCLUDE_PERFETTO_EXT_BASE_PERIODIC_TASK_H_
2676 
2677 #include <functional>
2678 
2679 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
2680 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
2681 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
2682 
2683 namespace perfetto {
2684 namespace base {
2685 
2686 class TaskRunner;
2687 
2688 // A periodic task utility class. It wraps the logic necessary to do periodic
2689 // tasks using a TaskRunner, taking care of subtleties like ensuring that
2690 // outstanding tasks are cancelled after reset/dtor.
2691 // Tasks are aligned on wall time, this is to ensure that when using multiple
2692 // periodic tasks, they happen at the same time, minimizing wakeups.
2693 // On Linux/Android it also supports suspend-aware mode (via timerfd). On other
2694 // operating systems it falls back to PostDelayedTask, which is not
2695 // suspend-aware.
2696 // TODO(primiano): this should probably become a periodic timer scheduler, so we
2697 // can use one FD for everything rather than one FD per task. For now we take
2698 // the hit of a FD-per-task to keep this low-risk.
2699 class PeriodicTask {
2700  public:
2701   explicit PeriodicTask(base::TaskRunner*);
2702   ~PeriodicTask();  // Calls Reset().
2703 
2704   struct Args {
2705     uint32_t period_ms = 0;
2706     std::function<void()> task = nullptr;
2707     bool start_first_task_immediately = false;
2708     bool use_suspend_aware_timer = false;
2709   };
2710 
2711   void Start(Args);
2712 
2713   // Safe to be called multiple times, even without calling Start():
2714   void Reset();
2715 
2716   // No copy or move. WeakPtr-wrapped pointers to |this| are posted on the
2717   // task runner, this class is not easily movable.
2718   PeriodicTask(const PeriodicTask&) = delete;
2719   PeriodicTask& operator=(const PeriodicTask&) = delete;
2720   PeriodicTask(PeriodicTask&&) = delete;
2721   PeriodicTask& operator=(PeriodicTask&&) = delete;
2722 
timer_fd_for_testing()2723   base::PlatformHandle timer_fd_for_testing() { return *timer_fd_; }
2724 
2725  private:
2726   static void RunTaskAndPostNext(base::WeakPtr<PeriodicTask>,
2727                                  uint32_t generation);
2728   void PostNextTask();
2729   void ResetTimerFd();
2730 
2731   base::TaskRunner* const task_runner_;
2732   Args args_;
2733   uint32_t generation_ = 0;
2734   base::ScopedPlatformHandle timer_fd_;
2735 
2736   PERFETTO_THREAD_CHECKER(thread_checker_)
2737   base::WeakPtrFactory<PeriodicTask> weak_ptr_factory_;  // Keep last.
2738 };
2739 
2740 }  // namespace base
2741 }  // namespace perfetto
2742 
2743 #endif  // INCLUDE_PERFETTO_EXT_BASE_PERIODIC_TASK_H_
2744 /*
2745  * Copyright (C) 2021 The Android Open Source Project
2746  *
2747  * Licensed under the Apache License, Version 2.0 (the "License");
2748  * you may not use this file except in compliance with the License.
2749  * You may obtain a copy of the License at
2750  *
2751  *      http://www.apache.org/licenses/LICENSE-2.0
2752  *
2753  * Unless required by applicable law or agreed to in writing, software
2754  * distributed under the License is distributed on an "AS IS" BASIS,
2755  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2756  * See the License for the specific language governing permissions and
2757  * limitations under the License.
2758  */
2759 
2760 // gen_amalgamated expanded: #include "perfetto/ext/base/periodic_task.h"
2761 
2762 #include <limits>
2763 
2764 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
2765 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
2766 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
2767 // gen_amalgamated expanded: #include "perfetto/base/time.h"
2768 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
2769 
2770 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
2771     (PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && __ANDROID_API__ >= 19)
2772 #include <sys/timerfd.h>
2773 #endif
2774 
2775 namespace perfetto {
2776 namespace base {
2777 
2778 namespace {
CreateTimerFd(uint32_t period_ms)2779 base::ScopedPlatformHandle CreateTimerFd(uint32_t period_ms) {
2780 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
2781     (PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && __ANDROID_API__ >= 19)
2782   base::ScopedPlatformHandle tfd(
2783       timerfd_create(CLOCK_BOOTTIME, TFD_CLOEXEC | TFD_NONBLOCK));
2784   // The initial phase, aligned on wall clock.
2785   uint32_t phase_ms =
2786       period_ms -
2787       static_cast<uint32_t>(base::GetBootTimeNs().count() % period_ms);
2788   struct itimerspec its {};
2789   // The "1 +" is to make sure that we never pass a zero it_value in the
2790   // unlikely case of phase_ms being 0. That would cause the timer to be
2791   // considered disarmed by timerfd_settime.
2792   its.it_value.tv_sec = static_cast<time_t>(phase_ms / 1000u);
2793   its.it_value.tv_nsec = 1 + static_cast<long>((phase_ms % 1000u) * 1000000u);
2794   its.it_interval.tv_sec = static_cast<time_t>(period_ms / 1000u);
2795   its.it_interval.tv_nsec = static_cast<long>((period_ms % 1000u) * 1000000u);
2796   if (timerfd_settime(*tfd, 0, &its, nullptr) < 0)
2797     return base::ScopedPlatformHandle();
2798   return tfd;
2799 #else
2800   base::ignore_result(period_ms);
2801   return base::ScopedPlatformHandle();
2802 #endif
2803 }
2804 }  // namespace
2805 
PeriodicTask(base::TaskRunner * task_runner)2806 PeriodicTask::PeriodicTask(base::TaskRunner* task_runner)
2807     : task_runner_(task_runner), weak_ptr_factory_(this) {}
2808 
~PeriodicTask()2809 PeriodicTask::~PeriodicTask() {
2810   Reset();
2811 }
2812 
Start(Args args)2813 void PeriodicTask::Start(Args args) {
2814   PERFETTO_DCHECK_THREAD(thread_checker_);
2815   Reset();
2816   if (args.period_ms == 0 || !args.task) {
2817     PERFETTO_DCHECK(args.period_ms > 0);
2818     PERFETTO_DCHECK(args.task);
2819     return;
2820   }
2821   args_ = std::move(args);
2822   if (args_.use_suspend_aware_timer) {
2823     timer_fd_ = CreateTimerFd(args_.period_ms);
2824     if (timer_fd_) {
2825       auto weak_this = weak_ptr_factory_.GetWeakPtr();
2826       task_runner_->AddFileDescriptorWatch(
2827           *timer_fd_,
2828           std::bind(PeriodicTask::RunTaskAndPostNext, weak_this, generation_));
2829     } else {
2830       PERFETTO_DPLOG("timerfd not supported, falling back on PostDelayedTask");
2831     }
2832   }  // if (use_suspend_aware_timer).
2833 
2834   if (!timer_fd_)
2835     PostNextTask();
2836 
2837   if (args_.start_first_task_immediately)
2838     args_.task();
2839 }
2840 
PostNextTask()2841 void PeriodicTask::PostNextTask() {
2842   PERFETTO_DCHECK_THREAD(thread_checker_);
2843   PERFETTO_DCHECK(args_.period_ms > 0);
2844   PERFETTO_DCHECK(!timer_fd_);
2845   uint32_t delay_ms =
2846       args_.period_ms -
2847       static_cast<uint32_t>(base::GetWallTimeMs().count() % args_.period_ms);
2848   auto weak_this = weak_ptr_factory_.GetWeakPtr();
2849   task_runner_->PostDelayedTask(
2850       std::bind(PeriodicTask::RunTaskAndPostNext, weak_this, generation_),
2851       delay_ms);
2852 }
2853 
2854 // static
2855 // This function can be called in two ways (both from the TaskRunner):
2856 // 1. When using a timerfd, this task is registered as a FD watch.
2857 // 2. When using PostDelayedTask, this is the task posted on the TaskRunner.
RunTaskAndPostNext(base::WeakPtr<PeriodicTask> thiz,uint32_t generation)2858 void PeriodicTask::RunTaskAndPostNext(base::WeakPtr<PeriodicTask> thiz,
2859                                       uint32_t generation) {
2860   if (!thiz || !thiz->args_.task || generation != thiz->generation_)
2861     return;  // Destroyed or Reset() in the meanwhile.
2862   PERFETTO_DCHECK_THREAD(thiz->thread_checker_);
2863   if (thiz->timer_fd_) {
2864 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2865     PERFETTO_FATAL("timerfd for periodic tasks unsupported on Windows");
2866 #else
2867     // If we are using a timerfd there is no need to repeatedly call
2868     // PostDelayedTask(). The kernel will wakeup the timer fd periodically. We
2869     // just need to read() it.
2870     uint64_t ignored = 0;
2871     errno = 0;
2872     auto rsize = base::Read(*thiz->timer_fd_, &ignored, sizeof(&ignored));
2873     if (rsize != sizeof(uint64_t)) {
2874       if (errno == EAGAIN)
2875         return;  // A spurious wakeup. Rare, but can happen, just ignore.
2876       PERFETTO_PLOG("read(timerfd) failed, falling back on PostDelayedTask");
2877       thiz->ResetTimerFd();
2878     }
2879 #endif
2880   }
2881   // The repetition of the if() is to deal with the ResetTimerFd() case above.
2882   if (!thiz->timer_fd_) {
2883     thiz->PostNextTask();
2884   }
2885   // Create a copy of the task in the unlikely event that the task ends up
2886   // up destroying the PeriodicTask object or calling Reset() on it. That would
2887   // cause a reset of the args_.task itself, which would invalidate the task
2888   // bind state while we are invoking it.
2889   auto task = thiz->args_.task;
2890   task();
2891 }
2892 
Reset()2893 void PeriodicTask::Reset() {
2894   PERFETTO_DCHECK_THREAD(thread_checker_);
2895   ++generation_;
2896   args_ = Args();
2897   PERFETTO_DCHECK(!args_.task);
2898   ResetTimerFd();
2899 }
2900 
ResetTimerFd()2901 void PeriodicTask::ResetTimerFd() {
2902   if (!timer_fd_)
2903     return;
2904   task_runner_->RemoveFileDescriptorWatch(*timer_fd_);
2905   timer_fd_.reset();
2906 }
2907 
2908 }  // namespace base
2909 }  // namespace perfetto
2910 // gen_amalgamated begin source: src/base/pipe.cc
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 // gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
2928 
2929 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
2930 
2931 #include <fcntl.h>  // For O_BINARY (Windows) and F_SETxx (UNIX)
2932 
2933 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2934 #include <Windows.h>
2935 #include <namedpipeapi.h>
2936 #else
2937 #include <sys/types.h>
2938 #include <unistd.h>
2939 #endif
2940 
2941 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
2942 
2943 namespace perfetto {
2944 namespace base {
2945 
2946 Pipe::Pipe() = default;
2947 Pipe::Pipe(Pipe&&) noexcept = default;
2948 Pipe& Pipe::operator=(Pipe&&) = default;
2949 
Create(Flags flags)2950 Pipe Pipe::Create(Flags flags) {
2951   PlatformHandle fds[2];
2952 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2953   PERFETTO_CHECK(::CreatePipe(&fds[0], &fds[1], /*lpPipeAttributes=*/nullptr,
2954                               0 /*default size*/));
2955 #else
2956   PERFETTO_CHECK(pipe(fds) == 0);
2957   PERFETTO_CHECK(fcntl(fds[0], F_SETFD, FD_CLOEXEC) == 0);
2958   PERFETTO_CHECK(fcntl(fds[1], F_SETFD, FD_CLOEXEC) == 0);
2959 #endif
2960   Pipe p;
2961   p.rd.reset(fds[0]);
2962   p.wr.reset(fds[1]);
2963 
2964 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2965   if (flags == kBothNonBlock || flags == kRdNonBlock) {
2966     int cur_flags = fcntl(*p.rd, F_GETFL, 0);
2967     PERFETTO_CHECK(cur_flags >= 0);
2968     PERFETTO_CHECK(fcntl(*p.rd, F_SETFL, cur_flags | O_NONBLOCK) == 0);
2969   }
2970 
2971   if (flags == kBothNonBlock || flags == kWrNonBlock) {
2972     int cur_flags = fcntl(*p.wr, F_GETFL, 0);
2973     PERFETTO_CHECK(cur_flags >= 0);
2974     PERFETTO_CHECK(fcntl(*p.wr, F_SETFL, cur_flags | O_NONBLOCK) == 0);
2975   }
2976 #else
2977   PERFETTO_CHECK(flags == kBothBlock);
2978 #endif
2979   return p;
2980 }
2981 
2982 }  // namespace base
2983 }  // namespace perfetto
2984 // gen_amalgamated begin source: src/base/status.cc
2985 // gen_amalgamated begin header: include/perfetto/base/status.h
2986 /*
2987  * Copyright (C) 2019 The Android Open Source Project
2988  *
2989  * Licensed under the Apache License, Version 2.0 (the "License");
2990  * you may not use this file except in compliance with the License.
2991  * You may obtain a copy of the License at
2992  *
2993  *      http://www.apache.org/licenses/LICENSE-2.0
2994  *
2995  * Unless required by applicable law or agreed to in writing, software
2996  * distributed under the License is distributed on an "AS IS" BASIS,
2997  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2998  * See the License for the specific language governing permissions and
2999  * limitations under the License.
3000  */
3001 
3002 #ifndef INCLUDE_PERFETTO_BASE_STATUS_H_
3003 #define INCLUDE_PERFETTO_BASE_STATUS_H_
3004 
3005 #include <string>
3006 
3007 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
3008 // gen_amalgamated expanded: #include "perfetto/base/export.h"
3009 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
3010 
3011 namespace perfetto {
3012 namespace base {
3013 
3014 // Represents either the success or the failure message of a function.
3015 // This can used as the return type of functions which would usually return an
3016 // bool for success or int for errno but also wants to add some string context
3017 // (ususally for logging).
3018 class PERFETTO_EXPORT Status {
3019  public:
Status()3020   Status() : ok_(true) {}
Status(std::string msg)3021   explicit Status(std::string msg) : ok_(false), message_(std::move(msg)) {
3022     PERFETTO_CHECK(!message_.empty());
3023   }
3024 
3025   // Copy operations.
3026   Status(const Status&) = default;
3027   Status& operator=(const Status&) = default;
3028 
3029   // Move operations. The moved-from state is valid but unspecified.
3030   Status(Status&&) noexcept = default;
3031   Status& operator=(Status&&) = default;
3032 
ok() const3033   bool ok() const { return ok_; }
3034 
3035   // When ok() is false this returns the error message. Returns the empty string
3036   // otherwise.
message() const3037   const std::string& message() const { return message_; }
c_message() const3038   const char* c_message() const { return message_.c_str(); }
3039 
3040  private:
3041   bool ok_ = false;
3042   std::string message_;
3043 };
3044 
3045 // Returns a status object which represents the Ok status.
OkStatus()3046 inline Status OkStatus() {
3047   return Status();
3048 }
3049 
3050 PERFETTO_PRINTF_FORMAT(1, 2) Status ErrStatus(const char* format, ...);
3051 
3052 }  // namespace base
3053 }  // namespace perfetto
3054 
3055 #endif  // INCLUDE_PERFETTO_BASE_STATUS_H_
3056 /*
3057  * Copyright (C) 2020 The Android Open Source Project
3058  *
3059  * Licensed under the Apache License, Version 2.0 (the "License");
3060  * you may not use this file except in compliance with the License.
3061  * You may obtain a copy of the License at
3062  *
3063  *      http://www.apache.org/licenses/LICENSE-2.0
3064  *
3065  * Unless required by applicable law or agreed to in writing, software
3066  * distributed under the License is distributed on an "AS IS" BASIS,
3067  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3068  * See the License for the specific language governing permissions and
3069  * limitations under the License.
3070  */
3071 
3072 // gen_amalgamated expanded: #include "perfetto/base/status.h"
3073 
3074 #include <stdarg.h>
3075 
3076 namespace perfetto {
3077 namespace base {
3078 
ErrStatus(const char * format,...)3079 Status ErrStatus(const char* format, ...) {
3080   char buffer[1024];
3081   va_list ap;
3082   va_start(ap, format);
3083   vsnprintf(buffer, sizeof(buffer), format, ap);
3084   va_end(ap);
3085   Status status(buffer);
3086   return status;
3087 }
3088 
3089 }  // namespace base
3090 }  // namespace perfetto
3091 // gen_amalgamated begin source: src/base/string_splitter.cc
3092 // gen_amalgamated begin header: include/perfetto/ext/base/string_splitter.h
3093 /*
3094  * Copyright (C) 2018 The Android Open Source Project
3095  *
3096  * Licensed under the Apache License, Version 2.0 (the "License");
3097  * you may not use this file except in compliance with the License.
3098  * You may obtain a copy of the License at
3099  *
3100  *      http://www.apache.org/licenses/LICENSE-2.0
3101  *
3102  * Unless required by applicable law or agreed to in writing, software
3103  * distributed under the License is distributed on an "AS IS" BASIS,
3104  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3105  * See the License for the specific language governing permissions and
3106  * limitations under the License.
3107  */
3108 
3109 #ifndef INCLUDE_PERFETTO_EXT_BASE_STRING_SPLITTER_H_
3110 #define INCLUDE_PERFETTO_EXT_BASE_STRING_SPLITTER_H_
3111 
3112 #include <string>
3113 
3114 namespace perfetto {
3115 namespace base {
3116 
3117 // C++ version of strtok(). Splits a string without making copies or any heap
3118 // allocations. Destructs the original string passed in input.
3119 // Supports the special case of using \0 as a delimiter.
3120 // The token returned in output are valid as long as the input string is valid.
3121 class StringSplitter {
3122  public:
3123   // Can take ownership of the string if passed via std::move(), e.g.:
3124   // StringSplitter(std::move(str), '\n');
3125   StringSplitter(std::string, char delimiter);
3126 
3127   // Splits a C-string. The input string will be forcefully null-terminated (so
3128   // str[size - 1] should be == '\0' or the last char will be truncated).
3129   StringSplitter(char* str, size_t size, char delimiter);
3130 
3131   // Splits the current token from an outer StringSplitter instance. This is to
3132   // chain splitters as follows:
3133   // for (base::StringSplitter lines(x, '\n'); ss.Next();)
3134   //   for (base::StringSplitter words(&lines, ' '); words.Next();)
3135   StringSplitter(StringSplitter*, char delimiter);
3136 
3137   // Returns true if a token is found (in which case it will be stored in
3138   // cur_token()), false if no more tokens are found.
3139   bool Next();
3140 
3141   // Returns the current token iff last call to Next() returned true. In this
3142   // case it guarantees that the returned string is always null terminated.
3143   // In all other cases (before the 1st call to Next() and after Next() returns
3144   // false) returns nullptr.
cur_token()3145   char* cur_token() { return cur_; }
3146 
3147   // Returns the length of the current token (excluding the null terminator).
cur_token_size() const3148   size_t cur_token_size() const { return cur_size_; }
3149 
3150  private:
3151   StringSplitter(const StringSplitter&) = delete;
3152   StringSplitter& operator=(const StringSplitter&) = delete;
3153   void Initialize(char* str, size_t size);
3154 
3155   std::string str_;
3156   char* cur_;
3157   size_t cur_size_;
3158   char* next_;
3159   char* end_;  // STL-style, points one past the last char.
3160   const char delimiter_;
3161 };
3162 
3163 }  // namespace base
3164 }  // namespace perfetto
3165 
3166 #endif  // INCLUDE_PERFETTO_EXT_BASE_STRING_SPLITTER_H_
3167 /*
3168  * Copyright (C) 2018 The Android Open Source Project
3169  *
3170  * Licensed under the Apache License, Version 2.0 (the "License");
3171  * you may not use this file except in compliance with the License.
3172  * You may obtain a copy of the License at
3173  *
3174  *      http://www.apache.org/licenses/LICENSE-2.0
3175  *
3176  * Unless required by applicable law or agreed to in writing, software
3177  * distributed under the License is distributed on an "AS IS" BASIS,
3178  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3179  * See the License for the specific language governing permissions and
3180  * limitations under the License.
3181  */
3182 
3183 // gen_amalgamated expanded: #include "perfetto/ext/base/string_splitter.h"
3184 
3185 #include <utility>
3186 
3187 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
3188 
3189 namespace perfetto {
3190 namespace base {
3191 
StringSplitter(std::string str,char delimiter)3192 StringSplitter::StringSplitter(std::string str, char delimiter)
3193     : str_(std::move(str)), delimiter_(delimiter) {
3194   // It's legal to access str[str.size()] in C++11 (it always returns \0),
3195   // hence the +1 (which becomes just size() after the -1 in Initialize()).
3196   Initialize(&str_[0], str_.size() + 1);
3197 }
3198 
StringSplitter(char * str,size_t size,char delimiter)3199 StringSplitter::StringSplitter(char* str, size_t size, char delimiter)
3200     : delimiter_(delimiter) {
3201   Initialize(str, size);
3202 }
3203 
StringSplitter(StringSplitter * outer,char delimiter)3204 StringSplitter::StringSplitter(StringSplitter* outer, char delimiter)
3205     : delimiter_(delimiter) {
3206   Initialize(outer->cur_token(), outer->cur_token_size() + 1);
3207 }
3208 
Initialize(char * str,size_t size)3209 void StringSplitter::Initialize(char* str, size_t size) {
3210   PERFETTO_DCHECK(!size || str);
3211   next_ = str;
3212   end_ = str + size;
3213   cur_ = nullptr;
3214   cur_size_ = 0;
3215   if (size)
3216     next_[size - 1] = '\0';
3217 }
3218 
Next()3219 bool StringSplitter::Next() {
3220   for (; next_ < end_; next_++) {
3221     if (*next_ == delimiter_)
3222       continue;
3223     cur_ = next_;
3224     for (;; next_++) {
3225       if (*next_ == delimiter_) {
3226         cur_size_ = static_cast<size_t>(next_ - cur_);
3227         *(next_++) = '\0';
3228         break;
3229       }
3230       if (*next_ == '\0') {
3231         cur_size_ = static_cast<size_t>(next_ - cur_);
3232         next_ = end_;
3233         break;
3234       }
3235     }
3236     if (*cur_)
3237       return true;
3238     break;
3239   }
3240   cur_ = nullptr;
3241   cur_size_ = 0;
3242   return false;
3243 }
3244 
3245 }  // namespace base
3246 }  // namespace perfetto
3247 // gen_amalgamated begin source: src/base/string_utils.cc
3248 // gen_amalgamated begin header: include/perfetto/ext/base/string_utils.h
3249 // gen_amalgamated begin header: include/perfetto/ext/base/optional.h
3250 /*
3251  * Copyright (C) 2018 The Android Open Source Project
3252  *
3253  * Licensed under the Apache License, Version 2.0 (the "License");
3254  * you may not use this file except in compliance with the License.
3255  * You may obtain a copy of the License at
3256  *
3257  *      http://www.apache.org/licenses/LICENSE-2.0
3258  *
3259  * Unless required by applicable law or agreed to in writing, software
3260  * distributed under the License is distributed on an "AS IS" BASIS,
3261  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3262  * See the License for the specific language governing permissions and
3263  * limitations under the License.
3264  */
3265 
3266 #ifndef INCLUDE_PERFETTO_EXT_BASE_OPTIONAL_H_
3267 #define INCLUDE_PERFETTO_EXT_BASE_OPTIONAL_H_
3268 
3269 #include <functional>
3270 #include <type_traits>
3271 #include <utility>
3272 
3273 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
3274 
3275 namespace perfetto {
3276 namespace base {
3277 
3278 // Specification:
3279 // http://en.cppreference.com/w/cpp/utility/optional/in_place_t
3280 struct in_place_t {};
3281 
3282 // Specification:
3283 // http://en.cppreference.com/w/cpp/utility/optional/nullopt_t
3284 struct nullopt_t {
nullopt_tperfetto::base::nullopt_t3285   constexpr explicit nullopt_t(int) {}
3286 };
3287 
3288 // Specification:
3289 // http://en.cppreference.com/w/cpp/utility/optional/in_place
3290 constexpr in_place_t in_place = {};
3291 
3292 // Specification:
3293 // http://en.cppreference.com/w/cpp/utility/optional/nullopt
3294 constexpr nullopt_t nullopt(0);
3295 
3296 // Forward declaration, which is referred by following helpers.
3297 template <typename T>
3298 class Optional;
3299 
3300 namespace internal {
3301 
3302 template <typename T, bool = std::is_trivially_destructible<T>::value>
3303 struct OptionalStorageBase {
3304   // Initializing |empty_| here instead of using default member initializing
3305   // to avoid errors in g++ 4.8.
OptionalStorageBaseperfetto::base::internal::OptionalStorageBase3306   constexpr OptionalStorageBase() : empty_('\0') {}
3307 
3308   template <class... Args>
OptionalStorageBaseperfetto::base::internal::OptionalStorageBase3309   constexpr explicit OptionalStorageBase(in_place_t, Args&&... args)
3310       : is_populated_(true), value_(std::forward<Args>(args)...) {}
3311 
3312   // When T is not trivially destructible we must call its
3313   // destructor before deallocating its memory.
3314   // Note that this hides the (implicitly declared) move constructor, which
3315   // would be used for constexpr move constructor in OptionalStorage<T>.
3316   // It is needed iff T is trivially move constructible. However, the current
3317   // is_trivially_{copy,move}_constructible implementation requires
3318   // is_trivially_destructible (which looks a bug, cf:
3319   // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51452 and
3320   // http://cplusplus.github.io/LWG/lwg-active.html#2116), so it is not
3321   // necessary for this case at the moment. Please see also the destructor
3322   // comment in "is_trivially_destructible = true" specialization below.
~OptionalStorageBaseperfetto::base::internal::OptionalStorageBase3323   ~OptionalStorageBase() {
3324     if (is_populated_)
3325       value_.~T();
3326   }
3327 
3328   template <class... Args>
Initperfetto::base::internal::OptionalStorageBase3329   void Init(Args&&... args) {
3330     PERFETTO_DCHECK(!is_populated_);
3331     ::new (&value_) T(std::forward<Args>(args)...);
3332     is_populated_ = true;
3333   }
3334 
3335   bool is_populated_ = false;
3336   union {
3337     // |empty_| exists so that the union will always be initialized, even when
3338     // it doesn't contain a value. Union members must be initialized for the
3339     // constructor to be 'constexpr'.
3340     char empty_;
3341     T value_;
3342   };
3343 };
3344 
3345 template <typename T>
3346 struct OptionalStorageBase<T, true /* trivially destructible */> {
3347   // Initializing |empty_| here instead of using default member initializing
3348   // to avoid errors in g++ 4.8.
OptionalStorageBaseperfetto::base::internal::OptionalStorageBase3349   constexpr OptionalStorageBase() : empty_('\0') {}
3350 
3351   template <class... Args>
OptionalStorageBaseperfetto::base::internal::OptionalStorageBase3352   constexpr explicit OptionalStorageBase(in_place_t, Args&&... args)
3353       : is_populated_(true), value_(std::forward<Args>(args)...) {}
3354 
3355   // When T is trivially destructible (i.e. its destructor does nothing) there
3356   // is no need to call it. Implicitly defined destructor is trivial, because
3357   // both members (bool and union containing only variants which are trivially
3358   // destructible) are trivially destructible.
3359   // Explicitly-defaulted destructor is also trivial, but do not use it here,
3360   // because it hides the implicit move constructor. It is needed to implement
3361   // constexpr move constructor in OptionalStorage iff T is trivially move
3362   // constructible. Note that, if T is trivially move constructible, the move
3363   // constructor of OptionalStorageBase<T> is also implicitly defined and it is
3364   // trivially move constructor. If T is not trivially move constructible,
3365   // "not declaring move constructor without destructor declaration" here means
3366   // "delete move constructor", which works because any move constructor of
3367   // OptionalStorage will not refer to it in that case.
3368 
3369   template <class... Args>
Initperfetto::base::internal::OptionalStorageBase3370   void Init(Args&&... args) {
3371     PERFETTO_DCHECK(!is_populated_);
3372     ::new (&value_) T(std::forward<Args>(args)...);
3373     is_populated_ = true;
3374   }
3375 
3376   bool is_populated_ = false;
3377   union {
3378     // |empty_| exists so that the union will always be initialized, even when
3379     // it doesn't contain a value. Union members must be initialized for the
3380     // constructor to be 'constexpr'.
3381     char empty_;
3382     T value_;
3383   };
3384 };
3385 
3386 // Implement conditional constexpr copy and move constructors. These are
3387 // constexpr if is_trivially_{copy,move}_constructible<T>::value is true
3388 // respectively. If each is true, the corresponding constructor is defined as
3389 // "= default;", which generates a constexpr constructor (In this case,
3390 // the condition of constexpr-ness is satisfied because the base class also has
3391 // compiler generated constexpr {copy,move} constructors). Note that
3392 // placement-new is prohibited in constexpr.
3393 template <typename T, bool = std::is_trivially_copy_constructible<T>::value>
3394 struct OptionalStorage : OptionalStorageBase<T> {
3395   // This is no trivially {copy,move} constructible case. Other cases are
3396   // defined below as specializations.
3397 
3398   // Accessing the members of template base class requires explicit
3399   // declaration.
3400   using OptionalStorageBase<T>::is_populated_;
3401   using OptionalStorageBase<T>::value_;
3402   using OptionalStorageBase<T>::Init;
3403 
3404   // Inherit constructors (specifically, the in_place constructor).
3405   using OptionalStorageBase<T>::OptionalStorageBase;
3406 
3407   // User defined constructor deletes the default constructor.
3408   // Define it explicitly.
3409   OptionalStorage() = default;
3410 
OptionalStorageperfetto::base::internal::OptionalStorage3411   OptionalStorage(const OptionalStorage& other) : OptionalStorageBase<T>() {
3412     if (other.is_populated_)
3413       Init(other.value_);
3414   }
3415 
OptionalStorageperfetto::base::internal::OptionalStorage3416   OptionalStorage(OptionalStorage&& other) noexcept(
3417       std::is_nothrow_move_constructible<T>::value) {
3418     if (other.is_populated_)
3419       Init(std::move(other.value_));
3420   }
3421 };
3422 
3423 template <typename T>
3424 struct OptionalStorage<T, true /* trivially copy constructible */>
3425     : OptionalStorageBase<T> {
3426   using OptionalStorageBase<T>::is_populated_;
3427   using OptionalStorageBase<T>::value_;
3428   using OptionalStorageBase<T>::Init;
3429   using OptionalStorageBase<T>::OptionalStorageBase;
3430 
3431   OptionalStorage() = default;
3432   OptionalStorage(const OptionalStorage& other) = default;
3433 
OptionalStorageperfetto::base::internal::OptionalStorage3434   OptionalStorage(OptionalStorage&& other) noexcept(
3435       std::is_nothrow_move_constructible<T>::value) {
3436     if (other.is_populated_)
3437       Init(std::move(other.value_));
3438   }
3439 };
3440 
3441 // Base class to support conditionally usable copy-/move- constructors
3442 // and assign operators.
3443 template <typename T>
3444 class OptionalBase {
3445   // This class provides implementation rather than public API, so everything
3446   // should be hidden. Often we use composition, but we cannot in this case
3447   // because of C++ language restriction.
3448  protected:
3449   constexpr OptionalBase() = default;
3450   constexpr OptionalBase(const OptionalBase& other) = default;
3451   constexpr OptionalBase(OptionalBase&& other) = default;
3452 
3453   template <class... Args>
OptionalBase(in_place_t,Args &&...args)3454   constexpr explicit OptionalBase(in_place_t, Args&&... args)
3455       : storage_(in_place, std::forward<Args>(args)...) {}
3456 
3457   // Implementation of converting constructors.
3458   template <typename U>
OptionalBase(const OptionalBase<U> & other)3459   explicit OptionalBase(const OptionalBase<U>& other) {
3460     if (other.storage_.is_populated_)
3461       storage_.Init(other.storage_.value_);
3462   }
3463 
3464   template <typename U>
OptionalBase(OptionalBase<U> && other)3465   explicit OptionalBase(OptionalBase<U>&& other) {
3466     if (other.storage_.is_populated_)
3467       storage_.Init(std::move(other.storage_.value_));
3468   }
3469 
3470   ~OptionalBase() = default;
3471 
operator =(const OptionalBase & other)3472   OptionalBase& operator=(const OptionalBase& other) {
3473     CopyAssign(other);
3474     return *this;
3475   }
3476 
operator =(OptionalBase && other)3477   OptionalBase& operator=(OptionalBase&& other) noexcept(
3478       std::is_nothrow_move_assignable<T>::value&&
3479           std::is_nothrow_move_constructible<T>::value) {
3480     MoveAssign(std::move(other));
3481     return *this;
3482   }
3483 
3484   template <typename U>
CopyAssign(const OptionalBase<U> & other)3485   void CopyAssign(const OptionalBase<U>& other) {
3486     if (other.storage_.is_populated_)
3487       InitOrAssign(other.storage_.value_);
3488     else
3489       FreeIfNeeded();
3490   }
3491 
3492   template <typename U>
MoveAssign(OptionalBase<U> && other)3493   void MoveAssign(OptionalBase<U>&& other) {
3494     if (other.storage_.is_populated_)
3495       InitOrAssign(std::move(other.storage_.value_));
3496     else
3497       FreeIfNeeded();
3498   }
3499 
3500   template <typename U>
InitOrAssign(U && value)3501   void InitOrAssign(U&& value) {
3502     if (storage_.is_populated_)
3503       storage_.value_ = std::forward<U>(value);
3504     else
3505       storage_.Init(std::forward<U>(value));
3506   }
3507 
FreeIfNeeded()3508   void FreeIfNeeded() {
3509     if (!storage_.is_populated_)
3510       return;
3511     storage_.value_.~T();
3512     storage_.is_populated_ = false;
3513   }
3514 
3515   // For implementing conversion, allow access to other typed OptionalBase
3516   // class.
3517   template <typename U>
3518   friend class OptionalBase;
3519 
3520   OptionalStorage<T> storage_;
3521 };
3522 
3523 // The following {Copy,Move}{Constructible,Assignable} structs are helpers to
3524 // implement constructor/assign-operator overloading. Specifically, if T is
3525 // is not movable but copyable, Optional<T>'s move constructor should not
3526 // participate in overload resolution. This inheritance trick implements that.
3527 template <bool is_copy_constructible>
3528 struct CopyConstructible {};
3529 
3530 template <>
3531 struct CopyConstructible<false> {
3532   constexpr CopyConstructible() = default;
3533   constexpr CopyConstructible(const CopyConstructible&) = delete;
3534   constexpr CopyConstructible(CopyConstructible&&) = default;
3535   CopyConstructible& operator=(const CopyConstructible&) = default;
3536   CopyConstructible& operator=(CopyConstructible&&) = default;
3537 };
3538 
3539 template <bool is_move_constructible>
3540 struct MoveConstructible {};
3541 
3542 template <>
3543 struct MoveConstructible<false> {
3544   constexpr MoveConstructible() = default;
3545   constexpr MoveConstructible(const MoveConstructible&) = default;
3546   constexpr MoveConstructible(MoveConstructible&&) = delete;
3547   MoveConstructible& operator=(const MoveConstructible&) = default;
3548   MoveConstructible& operator=(MoveConstructible&&) = default;
3549 };
3550 
3551 template <bool is_copy_assignable>
3552 struct CopyAssignable {};
3553 
3554 template <>
3555 struct CopyAssignable<false> {
3556   constexpr CopyAssignable() = default;
3557   constexpr CopyAssignable(const CopyAssignable&) = default;
3558   constexpr CopyAssignable(CopyAssignable&&) = default;
3559   CopyAssignable& operator=(const CopyAssignable&) = delete;
3560   CopyAssignable& operator=(CopyAssignable&&) = default;
3561 };
3562 
3563 template <bool is_move_assignable>
3564 struct MoveAssignable {};
3565 
3566 template <>
3567 struct MoveAssignable<false> {
3568   constexpr MoveAssignable() = default;
3569   constexpr MoveAssignable(const MoveAssignable&) = default;
3570   constexpr MoveAssignable(MoveAssignable&&) = default;
3571   MoveAssignable& operator=(const MoveAssignable&) = default;
3572   MoveAssignable& operator=(MoveAssignable&&) = delete;
3573 };
3574 
3575 // Helper to conditionally enable converting constructors and assign operators.
3576 template <typename T, typename U>
3577 struct IsConvertibleFromOptional
3578     : std::integral_constant<
3579           bool,
3580           std::is_constructible<T, Optional<U>&>::value ||
3581               std::is_constructible<T, const Optional<U>&>::value ||
3582               std::is_constructible<T, Optional<U>&&>::value ||
3583               std::is_constructible<T, const Optional<U>&&>::value ||
3584               std::is_convertible<Optional<U>&, T>::value ||
3585               std::is_convertible<const Optional<U>&, T>::value ||
3586               std::is_convertible<Optional<U>&&, T>::value ||
3587               std::is_convertible<const Optional<U>&&, T>::value> {};
3588 
3589 template <typename T, typename U>
3590 struct IsAssignableFromOptional
3591     : std::integral_constant<
3592           bool,
3593           IsConvertibleFromOptional<T, U>::value ||
3594               std::is_assignable<T&, Optional<U>&>::value ||
3595               std::is_assignable<T&, const Optional<U>&>::value ||
3596               std::is_assignable<T&, Optional<U>&&>::value ||
3597               std::is_assignable<T&, const Optional<U>&&>::value> {};
3598 
3599 // Forward compatibility for C++17.
3600 // Introduce one more deeper nested namespace to avoid leaking using std::swap.
3601 namespace swappable_impl {
3602 using std::swap;
3603 
3604 struct IsSwappableImpl {
3605   // Tests if swap can be called. Check<T&>(0) returns true_type iff swap is
3606   // available for T. Otherwise, Check's overload resolution falls back to
3607   // Check(...) declared below thanks to SFINAE, so returns false_type.
3608   template <typename T>
3609   static auto Check(int)
3610       -> decltype(swap(std::declval<T>(), std::declval<T>()), std::true_type());
3611 
3612   template <typename T>
3613   static std::false_type Check(...);
3614 };
3615 }  // namespace swappable_impl
3616 
3617 template <typename T>
3618 struct IsSwappable : decltype(swappable_impl::IsSwappableImpl::Check<T&>(0)) {};
3619 
3620 // Forward compatibility for C++20.
3621 template <typename T>
3622 using RemoveCvRefT =
3623     typename std::remove_cv<typename std::remove_reference<T>::type>::type;
3624 
3625 }  // namespace internal
3626 
3627 // On Windows, by default, empty-base class optimization does not work,
3628 // which means even if the base class is empty struct, it still consumes one
3629 // byte for its body. __declspec(empty_bases) enables the optimization.
3630 // cf)
3631 // https://blogs.msdn.microsoft.com/vcblog/2016/03/30/optimizing-the-layout-of-empty-base-classes-in-vs2015-update-2-3/
3632 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
3633     !PERFETTO_BUILDFLAG(PERFETTO_COMPILER_GCC)
3634 #define OPTIONAL_DECLSPEC_EMPTY_BASES __declspec(empty_bases)
3635 #else
3636 #define OPTIONAL_DECLSPEC_EMPTY_BASES
3637 #endif
3638 
3639 // base::Optional is a Chromium version of the C++17 optional class:
3640 // std::optional documentation:
3641 // http://en.cppreference.com/w/cpp/utility/optional
3642 // Chromium documentation:
3643 // https://chromium.googlesource.com/chromium/src/+/master/docs/optional.md
3644 //
3645 // These are the differences between the specification and the implementation:
3646 // - Constructors do not use 'constexpr' as it is a C++14 extension.
3647 // - 'constexpr' might be missing in some places for reasons specified locally.
3648 // - No exceptions are thrown, because they are banned from Chromium.
3649 //   Marked noexcept for only move constructor and move assign operators.
3650 // - All the non-members are in the 'base' namespace instead of 'std'.
3651 //
3652 // Note that T cannot have a constructor T(Optional<T>) etc. Optional<T>
3653 // PERFETTO_CHECKs T's constructor (specifically via IsConvertibleFromOptional),
3654 // and in the PERFETTO_CHECK whether T can be constructible from Optional<T>,
3655 // which is recursive so it does not work. As of Feb 2018, std::optional C++17
3656 // implementation in both clang and gcc has same limitation. MSVC SFINAE looks
3657 // to have different behavior, but anyway it reports an error, too.
3658 //
3659 // This file is a modified version of optional.h from Chromium at revision
3660 // 5e71bd454e60511c1293c0c686544aaa76094424. The changes remove C++14/C++17
3661 // specific code and replace with C++11 counterparts.
3662 template <typename T>
3663 class OPTIONAL_DECLSPEC_EMPTY_BASES Optional
3664     : public internal::OptionalBase<T>,
3665       public internal::CopyConstructible<std::is_copy_constructible<T>::value>,
3666       public internal::MoveConstructible<std::is_move_constructible<T>::value>,
3667       public internal::CopyAssignable<std::is_copy_constructible<T>::value &&
3668                                       std::is_copy_assignable<T>::value>,
3669       public internal::MoveAssignable<std::is_move_constructible<T>::value &&
3670                                       std::is_move_assignable<T>::value> {
3671  public:
3672 #undef OPTIONAL_DECLSPEC_EMPTY_BASES
3673   using value_type = T;
3674 
3675   // Defer default/copy/move constructor implementation to OptionalBase.
3676   constexpr Optional() = default;
3677   constexpr Optional(const Optional& other) = default;
3678   constexpr Optional(Optional&& other) noexcept(
3679       std::is_nothrow_move_constructible<T>::value) = default;
3680 
Optional(nullopt_t)3681   constexpr Optional(nullopt_t) {}  // NOLINT(runtime/explicit)
3682 
3683   // Converting copy constructor. "explicit" only if
3684   // std::is_convertible<const U&, T>::value is false. It is implemented by
3685   // declaring two almost same constructors, but that condition in enable_if_t
3686   // is different, so that either one is chosen, thanks to SFINAE.
3687   template <typename U,
3688             typename std::enable_if<
3689                 std::is_constructible<T, const U&>::value &&
3690                     !internal::IsConvertibleFromOptional<T, U>::value &&
3691                     std::is_convertible<const U&, T>::value,
3692                 bool>::type = false>
Optional(const Optional<U> & other)3693   Optional(const Optional<U>& other) : internal::OptionalBase<T>(other) {}
3694 
3695   template <typename U,
3696             typename std::enable_if<
3697                 std::is_constructible<T, const U&>::value &&
3698                     !internal::IsConvertibleFromOptional<T, U>::value &&
3699                     !std::is_convertible<const U&, T>::value,
3700                 bool>::type = false>
Optional(const Optional<U> & other)3701   explicit Optional(const Optional<U>& other)
3702       : internal::OptionalBase<T>(other) {}
3703 
3704   // Converting move constructor. Similar to converting copy constructor,
3705   // declaring two (explicit and non-explicit) constructors.
3706   template <typename U,
3707             typename std::enable_if<
3708                 std::is_constructible<T, U&&>::value &&
3709                     !internal::IsConvertibleFromOptional<T, U>::value &&
3710                     std::is_convertible<U&&, T>::value,
3711                 bool>::type = false>
Optional(Optional<U> && other)3712   Optional(Optional<U>&& other) : internal::OptionalBase<T>(std::move(other)) {}
3713 
3714   template <typename U,
3715             typename std::enable_if<
3716                 std::is_constructible<T, U&&>::value &&
3717                     !internal::IsConvertibleFromOptional<T, U>::value &&
3718                     !std::is_convertible<U&&, T>::value,
3719                 bool>::type = false>
Optional(Optional<U> && other)3720   explicit Optional(Optional<U>&& other)
3721       : internal::OptionalBase<T>(std::move(other)) {}
3722 
3723   template <class... Args>
Optional(in_place_t,Args &&...args)3724   constexpr explicit Optional(in_place_t, Args&&... args)
3725       : internal::OptionalBase<T>(in_place, std::forward<Args>(args)...) {}
3726 
3727   template <class U,
3728             class... Args,
3729             class = typename std::enable_if<
3730                 std::is_constructible<value_type,
3731                                       std::initializer_list<U>&,
3732                                       Args...>::value>::type>
Optional(in_place_t,std::initializer_list<U> il,Args &&...args)3733   constexpr explicit Optional(in_place_t,
3734                               std::initializer_list<U> il,
3735                               Args&&... args)
3736       : internal::OptionalBase<T>(in_place, il, std::forward<Args>(args)...) {}
3737 
3738   // Forward value constructor. Similar to converting constructors,
3739   // conditionally explicit.
3740   template <
3741       typename U = value_type,
3742       typename std::enable_if<
3743           std::is_constructible<T, U&&>::value &&
3744               !std::is_same<internal::RemoveCvRefT<U>, in_place_t>::value &&
3745               !std::is_same<internal::RemoveCvRefT<U>, Optional<T>>::value &&
3746               std::is_convertible<U&&, T>::value,
3747           bool>::type = false>
Optional(U && value)3748   constexpr Optional(U&& value)
3749       : internal::OptionalBase<T>(in_place, std::forward<U>(value)) {}
3750 
3751   template <
3752       typename U = value_type,
3753       typename std::enable_if<
3754           std::is_constructible<T, U&&>::value &&
3755               !std::is_same<internal::RemoveCvRefT<U>, in_place_t>::value &&
3756               !std::is_same<internal::RemoveCvRefT<U>, Optional<T>>::value &&
3757               !std::is_convertible<U&&, T>::value,
3758           bool>::type = false>
Optional(U && value)3759   constexpr explicit Optional(U&& value)
3760       : internal::OptionalBase<T>(in_place, std::forward<U>(value)) {}
3761 
3762   ~Optional() = default;
3763 
3764   // Defer copy-/move- assign operator implementation to OptionalBase.
3765   Optional& operator=(const Optional& other) = default;
3766   Optional& operator=(Optional&& other) noexcept(
3767       std::is_nothrow_move_assignable<T>::value&&
3768           std::is_nothrow_move_constructible<T>::value) = default;
3769 
operator =(nullopt_t)3770   Optional& operator=(nullopt_t) {
3771     FreeIfNeeded();
3772     return *this;
3773   }
3774 
3775   // Perfect-forwarded assignment.
3776   template <typename U>
3777   typename std::enable_if<
3778       !std::is_same<internal::RemoveCvRefT<U>, Optional<T>>::value &&
3779           std::is_constructible<T, U>::value &&
3780           std::is_assignable<T&, U>::value &&
3781           (!std::is_scalar<T>::value ||
3782            !std::is_same<typename std::decay<U>::type, T>::value),
3783       Optional&>::type
operator =(U && value)3784   operator=(U&& value) {
3785     InitOrAssign(std::forward<U>(value));
3786     return *this;
3787   }
3788 
3789   // Copy assign the state of other.
3790   template <typename U>
3791   typename std::enable_if<!internal::IsAssignableFromOptional<T, U>::value &&
3792                               std::is_constructible<T, const U&>::value &&
3793                               std::is_assignable<T&, const U&>::value,
3794                           Optional&>::type
operator =(const Optional<U> & other)3795   operator=(const Optional<U>& other) {
3796     CopyAssign(other);
3797     return *this;
3798   }
3799 
3800   // Move assign the state of other.
3801   template <typename U>
3802   typename std::enable_if<!internal::IsAssignableFromOptional<T, U>::value &&
3803                               std::is_constructible<T, U>::value &&
3804                               std::is_assignable<T&, U>::value,
3805                           Optional&>::type
operator =(Optional<U> && other)3806   operator=(Optional<U>&& other) {
3807     MoveAssign(std::move(other));
3808     return *this;
3809   }
3810 
operator ->() const3811   const T* operator->() const {
3812     PERFETTO_DCHECK(storage_.is_populated_);
3813     return &storage_.value_;
3814   }
3815 
operator ->()3816   T* operator->() {
3817     PERFETTO_DCHECK(storage_.is_populated_);
3818     return &storage_.value_;
3819   }
3820 
operator *() const3821   const T& operator*() const& {
3822     PERFETTO_DCHECK(storage_.is_populated_);
3823     return storage_.value_;
3824   }
3825 
operator *()3826   T& operator*() & {
3827     PERFETTO_DCHECK(storage_.is_populated_);
3828     return storage_.value_;
3829   }
3830 
operator *() const3831   const T&& operator*() const&& {
3832     PERFETTO_DCHECK(storage_.is_populated_);
3833     return std::move(storage_.value_);
3834   }
3835 
operator *()3836   T&& operator*() && {
3837     PERFETTO_DCHECK(storage_.is_populated_);
3838     return std::move(storage_.value_);
3839   }
3840 
operator bool() const3841   constexpr explicit operator bool() const { return storage_.is_populated_; }
3842 
has_value() const3843   constexpr bool has_value() const { return storage_.is_populated_; }
3844 
value()3845   T& value() & {
3846     PERFETTO_CHECK(storage_.is_populated_);
3847     return storage_.value_;
3848   }
3849 
value() const3850   const T& value() const& {
3851     PERFETTO_CHECK(storage_.is_populated_);
3852     return storage_.value_;
3853   }
3854 
value()3855   T&& value() && {
3856     PERFETTO_CHECK(storage_.is_populated_);
3857     return std::move(storage_.value_);
3858   }
3859 
value() const3860   const T&& value() const&& {
3861     PERFETTO_CHECK(storage_.is_populated_);
3862     return std::move(storage_.value_);
3863   }
3864 
3865   template <class U>
value_or(U && default_value) const3866   constexpr T value_or(U&& default_value) const& {
3867     static_assert(std::is_convertible<U, T>::value,
3868                   "U must be convertible to T");
3869     return storage_.is_populated_
3870                ? storage_.value_
3871                : static_cast<T>(std::forward<U>(default_value));
3872   }
3873 
3874   template <class U>
value_or(U && default_value)3875   T value_or(U&& default_value) && {
3876     static_assert(std::is_convertible<U, T>::value,
3877                   "U must be convertible to T");
3878     return storage_.is_populated_
3879                ? std::move(storage_.value_)
3880                : static_cast<T>(std::forward<U>(default_value));
3881   }
3882 
swap(Optional & other)3883   void swap(Optional& other) {
3884     if (!storage_.is_populated_ && !other.storage_.is_populated_)
3885       return;
3886 
3887     if (storage_.is_populated_ != other.storage_.is_populated_) {
3888       if (storage_.is_populated_) {
3889         other.storage_.Init(std::move(storage_.value_));
3890         FreeIfNeeded();
3891       } else {
3892         storage_.Init(std::move(other.storage_.value_));
3893         other.FreeIfNeeded();
3894       }
3895       return;
3896     }
3897 
3898     PERFETTO_DCHECK(storage_.is_populated_ && other.storage_.is_populated_);
3899     using std::swap;
3900     swap(**this, *other);
3901   }
3902 
reset()3903   void reset() { FreeIfNeeded(); }
3904 
3905   template <class... Args>
emplace(Args &&...args)3906   T& emplace(Args&&... args) {
3907     FreeIfNeeded();
3908     storage_.Init(std::forward<Args>(args)...);
3909     return storage_.value_;
3910   }
3911 
3912   template <class U, class... Args>
3913   typename std::enable_if<
3914       std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value,
3915       T&>::type
emplace(std::initializer_list<U> il,Args &&...args)3916   emplace(std::initializer_list<U> il, Args&&... args) {
3917     FreeIfNeeded();
3918     storage_.Init(il, std::forward<Args>(args)...);
3919     return storage_.value_;
3920   }
3921 
3922  private:
3923   // Accessing template base class's protected member needs explicit
3924   // declaration to do so.
3925   using internal::OptionalBase<T>::CopyAssign;
3926   using internal::OptionalBase<T>::FreeIfNeeded;
3927   using internal::OptionalBase<T>::InitOrAssign;
3928   using internal::OptionalBase<T>::MoveAssign;
3929   using internal::OptionalBase<T>::storage_;
3930 };
3931 
3932 // Here after defines comparation operators. The definition follows
3933 // http://en.cppreference.com/w/cpp/utility/optional/operator_cmp
3934 // while bool() casting is replaced by has_value() to meet the chromium
3935 // style guide.
3936 template <class T, class U>
operator ==(const Optional<T> & lhs,const Optional<U> & rhs)3937 bool operator==(const Optional<T>& lhs, const Optional<U>& rhs) {
3938   if (lhs.has_value() != rhs.has_value())
3939     return false;
3940   if (!lhs.has_value())
3941     return true;
3942   return *lhs == *rhs;
3943 }
3944 
3945 template <class T, class U>
operator !=(const Optional<T> & lhs,const Optional<U> & rhs)3946 bool operator!=(const Optional<T>& lhs, const Optional<U>& rhs) {
3947   if (lhs.has_value() != rhs.has_value())
3948     return true;
3949   if (!lhs.has_value())
3950     return false;
3951   return *lhs != *rhs;
3952 }
3953 
3954 template <class T, class U>
operator <(const Optional<T> & lhs,const Optional<U> & rhs)3955 bool operator<(const Optional<T>& lhs, const Optional<U>& rhs) {
3956   if (!rhs.has_value())
3957     return false;
3958   if (!lhs.has_value())
3959     return true;
3960   return *lhs < *rhs;
3961 }
3962 
3963 template <class T, class U>
operator <=(const Optional<T> & lhs,const Optional<U> & rhs)3964 bool operator<=(const Optional<T>& lhs, const Optional<U>& rhs) {
3965   if (!lhs.has_value())
3966     return true;
3967   if (!rhs.has_value())
3968     return false;
3969   return *lhs <= *rhs;
3970 }
3971 
3972 template <class T, class U>
operator >(const Optional<T> & lhs,const Optional<U> & rhs)3973 bool operator>(const Optional<T>& lhs, const Optional<U>& rhs) {
3974   if (!lhs.has_value())
3975     return false;
3976   if (!rhs.has_value())
3977     return true;
3978   return *lhs > *rhs;
3979 }
3980 
3981 template <class T, class U>
operator >=(const Optional<T> & lhs,const Optional<U> & rhs)3982 bool operator>=(const Optional<T>& lhs, const Optional<U>& rhs) {
3983   if (!rhs.has_value())
3984     return true;
3985   if (!lhs.has_value())
3986     return false;
3987   return *lhs >= *rhs;
3988 }
3989 
3990 template <class T>
operator ==(const Optional<T> & opt,nullopt_t)3991 constexpr bool operator==(const Optional<T>& opt, nullopt_t) {
3992   return !opt;
3993 }
3994 
3995 template <class T>
operator ==(nullopt_t,const Optional<T> & opt)3996 constexpr bool operator==(nullopt_t, const Optional<T>& opt) {
3997   return !opt;
3998 }
3999 
4000 template <class T>
operator !=(const Optional<T> & opt,nullopt_t)4001 constexpr bool operator!=(const Optional<T>& opt, nullopt_t) {
4002   return opt.has_value();
4003 }
4004 
4005 template <class T>
operator !=(nullopt_t,const Optional<T> & opt)4006 constexpr bool operator!=(nullopt_t, const Optional<T>& opt) {
4007   return opt.has_value();
4008 }
4009 
4010 template <class T>
operator <(const Optional<T> &,nullopt_t)4011 constexpr bool operator<(const Optional<T>&, nullopt_t) {
4012   return false;
4013 }
4014 
4015 template <class T>
operator <(nullopt_t,const Optional<T> & opt)4016 constexpr bool operator<(nullopt_t, const Optional<T>& opt) {
4017   return opt.has_value();
4018 }
4019 
4020 template <class T>
operator <=(const Optional<T> & opt,nullopt_t)4021 constexpr bool operator<=(const Optional<T>& opt, nullopt_t) {
4022   return !opt;
4023 }
4024 
4025 template <class T>
operator <=(nullopt_t,const Optional<T> &)4026 constexpr bool operator<=(nullopt_t, const Optional<T>&) {
4027   return true;
4028 }
4029 
4030 template <class T>
operator >(const Optional<T> & opt,nullopt_t)4031 constexpr bool operator>(const Optional<T>& opt, nullopt_t) {
4032   return opt.has_value();
4033 }
4034 
4035 template <class T>
operator >(nullopt_t,const Optional<T> &)4036 constexpr bool operator>(nullopt_t, const Optional<T>&) {
4037   return false;
4038 }
4039 
4040 template <class T>
operator >=(const Optional<T> &,nullopt_t)4041 constexpr bool operator>=(const Optional<T>&, nullopt_t) {
4042   return true;
4043 }
4044 
4045 template <class T>
operator >=(nullopt_t,const Optional<T> & opt)4046 constexpr bool operator>=(nullopt_t, const Optional<T>& opt) {
4047   return !opt;
4048 }
4049 
4050 template <class T, class U>
operator ==(const Optional<T> & opt,const U & value)4051 constexpr bool operator==(const Optional<T>& opt, const U& value) {
4052   return opt.has_value() ? *opt == value : false;
4053 }
4054 
4055 template <class T, class U>
operator ==(const U & value,const Optional<T> & opt)4056 constexpr bool operator==(const U& value, const Optional<T>& opt) {
4057   return opt.has_value() ? value == *opt : false;
4058 }
4059 
4060 template <class T, class U>
operator !=(const Optional<T> & opt,const U & value)4061 constexpr bool operator!=(const Optional<T>& opt, const U& value) {
4062   return opt.has_value() ? *opt != value : true;
4063 }
4064 
4065 template <class T, class U>
operator !=(const U & value,const Optional<T> & opt)4066 constexpr bool operator!=(const U& value, const Optional<T>& opt) {
4067   return opt.has_value() ? value != *opt : true;
4068 }
4069 
4070 template <class T, class U>
operator <(const Optional<T> & opt,const U & value)4071 constexpr bool operator<(const Optional<T>& opt, const U& value) {
4072   return opt.has_value() ? *opt < value : true;
4073 }
4074 
4075 template <class T, class U>
operator <(const U & value,const Optional<T> & opt)4076 constexpr bool operator<(const U& value, const Optional<T>& opt) {
4077   return opt.has_value() ? value < *opt : false;
4078 }
4079 
4080 template <class T, class U>
operator <=(const Optional<T> & opt,const U & value)4081 constexpr bool operator<=(const Optional<T>& opt, const U& value) {
4082   return opt.has_value() ? *opt <= value : true;
4083 }
4084 
4085 template <class T, class U>
operator <=(const U & value,const Optional<T> & opt)4086 constexpr bool operator<=(const U& value, const Optional<T>& opt) {
4087   return opt.has_value() ? value <= *opt : false;
4088 }
4089 
4090 template <class T, class U>
operator >(const Optional<T> & opt,const U & value)4091 constexpr bool operator>(const Optional<T>& opt, const U& value) {
4092   return opt.has_value() ? *opt > value : false;
4093 }
4094 
4095 template <class T, class U>
operator >(const U & value,const Optional<T> & opt)4096 constexpr bool operator>(const U& value, const Optional<T>& opt) {
4097   return opt.has_value() ? value > *opt : true;
4098 }
4099 
4100 template <class T, class U>
operator >=(const Optional<T> & opt,const U & value)4101 constexpr bool operator>=(const Optional<T>& opt, const U& value) {
4102   return opt.has_value() ? *opt >= value : false;
4103 }
4104 
4105 template <class T, class U>
operator >=(const U & value,const Optional<T> & opt)4106 constexpr bool operator>=(const U& value, const Optional<T>& opt) {
4107   return opt.has_value() ? value >= *opt : true;
4108 }
4109 
4110 template <class T>
make_optional(T && value)4111 constexpr Optional<typename std::decay<T>::type> make_optional(T&& value) {
4112   return Optional<typename std::decay<T>::type>(std::forward<T>(value));
4113 }
4114 
4115 template <class T, class... Args>
make_optional(Args &&...args)4116 constexpr Optional<T> make_optional(Args&&... args) {
4117   return Optional<T>(in_place, std::forward<Args>(args)...);
4118 }
4119 
4120 template <class T, class U, class... Args>
make_optional(std::initializer_list<U> il,Args &&...args)4121 constexpr Optional<T> make_optional(std::initializer_list<U> il,
4122                                     Args&&... args) {
4123   return Optional<T>(in_place, il, std::forward<Args>(args)...);
4124 }
4125 
4126 // Partial specialization for a function template is not allowed. Also, it is
4127 // not allowed to add overload function to std namespace, while it is allowed
4128 // to specialize the template in std. Thus, swap() (kind of) overloading is
4129 // defined in base namespace, instead.
4130 template <class T>
4131 typename std::enable_if<std::is_move_constructible<T>::value &&
4132                         internal::IsSwappable<T>::value>::type
swap(Optional<T> & lhs,Optional<T> & rhs)4133 swap(Optional<T>& lhs, Optional<T>& rhs) {
4134   lhs.swap(rhs);
4135 }
4136 
4137 }  // namespace base
4138 }  // namespace perfetto
4139 
4140 template <class T>
4141 struct std::hash<perfetto::base::Optional<T>> {
operator ()std::hash4142   size_t operator()(const perfetto::base::Optional<T>& opt) const {
4143     return opt == perfetto::base::nullopt ? 0 : std::hash<T>()(*opt);
4144   }
4145 };
4146 
4147 #endif  // INCLUDE_PERFETTO_EXT_BASE_OPTIONAL_H_
4148 // gen_amalgamated begin header: include/perfetto/ext/base/string_view.h
4149 // gen_amalgamated begin header: include/perfetto/ext/base/hash.h
4150 /*
4151  * Copyright (C) 2019 The Android Open Source Project
4152  *
4153  * Licensed under the Apache License, Version 2.0 (the "License");
4154  * you may not use this file except in compliance with the License.
4155  * You may obtain a copy of the License at
4156  *
4157  *      http://www.apache.org/licenses/LICENSE-2.0
4158  *
4159  * Unless required by applicable law or agreed to in writing, software
4160  * distributed under the License is distributed on an "AS IS" BASIS,
4161  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4162  * See the License for the specific language governing permissions and
4163  * limitations under the License.
4164  */
4165 
4166 #ifndef INCLUDE_PERFETTO_EXT_BASE_HASH_H_
4167 #define INCLUDE_PERFETTO_EXT_BASE_HASH_H_
4168 
4169 #include <stddef.h>
4170 #include <stdint.h>
4171 #include <type_traits>
4172 
4173 namespace perfetto {
4174 namespace base {
4175 
4176 // A helper class which computes a 64-bit hash of the input data.
4177 // The algorithm used is FNV-1a as it is fast and easy to implement and has
4178 // relatively few collisions.
4179 // WARNING: This hash function should not be used for any cryptographic purpose.
4180 class Hash {
4181  public:
4182   // Creates an empty hash object
Hash()4183   Hash() {}
4184 
4185   // Hashes a numeric value.
4186   template <
4187       typename T,
4188       typename std::enable_if<std::is_arithmetic<T>::value, bool>::type = true>
Update(T data)4189   void Update(T data) {
4190     Update(reinterpret_cast<const char*>(&data), sizeof(data));
4191   }
4192 
4193   // Hashes a byte array.
Update(const char * data,size_t size)4194   void Update(const char* data, size_t size) {
4195     for (size_t i = 0; i < size; i++) {
4196       result_ ^= static_cast<uint8_t>(data[i]);
4197       result_ *= kFnv1a64Prime;
4198     }
4199   }
4200 
digest()4201   uint64_t digest() { return result_; }
4202 
4203  private:
4204   static constexpr uint64_t kFnv1a64OffsetBasis = 0xcbf29ce484222325;
4205   static constexpr uint64_t kFnv1a64Prime = 0x100000001b3;
4206 
4207   uint64_t result_ = kFnv1a64OffsetBasis;
4208 };
4209 
4210 }  // namespace base
4211 }  // namespace perfetto
4212 
4213 #endif  // INCLUDE_PERFETTO_EXT_BASE_HASH_H_
4214 /*
4215  * Copyright (C) 2018 The Android Open Source Project
4216  *
4217  * Licensed under the Apache License, Version 2.0 (the "License");
4218  * you may not use this file except in compliance with the License.
4219  * You may obtain a copy of the License at
4220  *
4221  *      http://www.apache.org/licenses/LICENSE-2.0
4222  *
4223  * Unless required by applicable law or agreed to in writing, software
4224  * distributed under the License is distributed on an "AS IS" BASIS,
4225  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4226  * See the License for the specific language governing permissions and
4227  * limitations under the License.
4228  */
4229 
4230 #ifndef INCLUDE_PERFETTO_EXT_BASE_STRING_VIEW_H_
4231 #define INCLUDE_PERFETTO_EXT_BASE_STRING_VIEW_H_
4232 
4233 #include <string.h>
4234 
4235 #include <algorithm>
4236 #include <string>
4237 
4238 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
4239 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
4240 // gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
4241 
4242 namespace perfetto {
4243 namespace base {
4244 
4245 // A string-like object that refers to a non-owned piece of memory.
4246 // Strings are internally NOT null terminated.
4247 class StringView {
4248  public:
4249   static constexpr size_t npos = static_cast<size_t>(-1);
4250 
StringView()4251   StringView() : data_(nullptr), size_(0) {}
4252   StringView(const StringView&) = default;
4253   StringView& operator=(const StringView&) = default;
StringView(const char * data,size_t size)4254   StringView(const char* data, size_t size) : data_(data), size_(size) {
4255     PERFETTO_DCHECK(size == 0 || data != nullptr);
4256   }
4257 
4258   // Allow implicit conversion from any class that has a |data| and |size| field
4259   // and has the kConvertibleToStringView trait (e.g., protozero::ConstChars).
4260   template <typename T, typename = std::enable_if<T::kConvertibleToStringView>>
StringView(const T & x)4261   StringView(const T& x) : StringView(x.data, x.size) {
4262     PERFETTO_DCHECK(x.size == 0 || x.data != nullptr);
4263   }
4264 
4265   // Creates a StringView from a null-terminated C string.
4266   // Deliberately not "explicit".
StringView(const char * cstr)4267   StringView(const char* cstr) : data_(cstr), size_(strlen(cstr)) {
4268     PERFETTO_DCHECK(cstr != nullptr);
4269   }
4270 
4271   // This instead has to be explicit, as creating a StringView out of a
4272   // std::string can be subtle.
StringView(const std::string & str)4273   explicit StringView(const std::string& str)
4274       : data_(str.data()), size_(str.size()) {}
4275 
empty() const4276   bool empty() const { return size_ == 0; }
size() const4277   size_t size() const { return size_; }
data() const4278   const char* data() const { return data_; }
begin() const4279   const char* begin() const { return data_; }
end() const4280   const char* end() const { return data_ + size_; }
4281 
at(size_t pos) const4282   char at(size_t pos) const {
4283     PERFETTO_DCHECK(pos < size_);
4284     return data_[pos];
4285   }
4286 
find(char c,size_t start_pos=0) const4287   size_t find(char c, size_t start_pos = 0) const {
4288     for (size_t i = start_pos; i < size_; ++i) {
4289       if (data_[i] == c)
4290         return i;
4291     }
4292     return npos;
4293   }
4294 
find(const StringView & str,size_t start_pos=0) const4295   size_t find(const StringView& str, size_t start_pos = 0) const {
4296     if (start_pos > size())
4297       return npos;
4298     auto it = std::search(begin() + start_pos, end(), str.begin(), str.end());
4299     size_t pos = static_cast<size_t>(it - begin());
4300     return pos + str.size() <= size() ? pos : npos;
4301   }
4302 
find(const char * str,size_t start_pos=0) const4303   size_t find(const char* str, size_t start_pos = 0) const {
4304     return find(StringView(str), start_pos);
4305   }
4306 
rfind(char c) const4307   size_t rfind(char c) const {
4308     for (size_t i = size_; i > 0; --i) {
4309       if (data_[i - 1] == c)
4310         return i - 1;
4311     }
4312     return npos;
4313   }
4314 
substr(size_t pos,size_t count=npos) const4315   StringView substr(size_t pos, size_t count = npos) const {
4316     if (pos >= size_)
4317       return StringView("", 0);
4318     size_t rcount = std::min(count, size_ - pos);
4319     return StringView(data_ + pos, rcount);
4320   }
4321 
CaseInsensitiveEq(const StringView & other)4322   bool CaseInsensitiveEq(const StringView& other) {
4323     if (size() != other.size())
4324       return false;
4325     if (size() == 0)
4326       return true;
4327 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4328     return _strnicmp(data(), other.data(), size()) == 0;
4329 #else
4330     return strncasecmp(data(), other.data(), size()) == 0;
4331 #endif
4332   }
4333 
ToStdString() const4334   std::string ToStdString() const {
4335     return data_ == nullptr ? "" : std::string(data_, size_);
4336   }
4337 
Hash() const4338   uint64_t Hash() const {
4339     base::Hash hasher;
4340     hasher.Update(data_, size_);
4341     return hasher.digest();
4342   }
4343 
4344  private:
4345   const char* data_ = nullptr;
4346   size_t size_ = 0;
4347 };
4348 
operator ==(const StringView & x,const StringView & y)4349 inline bool operator==(const StringView& x, const StringView& y) {
4350   if (x.size() != y.size())
4351     return false;
4352   if (x.size() == 0)
4353     return true;
4354   return memcmp(x.data(), y.data(), x.size()) == 0;
4355 }
4356 
operator !=(const StringView & x,const StringView & y)4357 inline bool operator!=(const StringView& x, const StringView& y) {
4358   return !(x == y);
4359 }
4360 
operator <(const StringView & x,const StringView & y)4361 inline bool operator<(const StringView& x, const StringView& y) {
4362   auto size = std::min(x.size(), y.size());
4363   if (size == 0)
4364     return x.size() < y.size();
4365   int result = memcmp(x.data(), y.data(), size);
4366   return result < 0 || (result == 0 && x.size() < y.size());
4367 }
4368 
operator >=(const StringView & x,const StringView & y)4369 inline bool operator>=(const StringView& x, const StringView& y) {
4370   return !(x < y);
4371 }
4372 
operator >(const StringView & x,const StringView & y)4373 inline bool operator>(const StringView& x, const StringView& y) {
4374   return y < x;
4375 }
4376 
operator <=(const StringView & x,const StringView & y)4377 inline bool operator<=(const StringView& x, const StringView& y) {
4378   return !(y < x);
4379 }
4380 
4381 }  // namespace base
4382 }  // namespace perfetto
4383 
4384 template <>
4385 struct std::hash<::perfetto::base::StringView> {
operator ()std::hash4386   size_t operator()(const ::perfetto::base::StringView& sv) const {
4387     return static_cast<size_t>(sv.Hash());
4388   }
4389 };
4390 
4391 #endif  // INCLUDE_PERFETTO_EXT_BASE_STRING_VIEW_H_
4392 /*
4393  * Copyright (C) 2018 The Android Open Source Project
4394  *
4395  * Licensed under the Apache License, Version 2.0 (the "License");
4396  * you may not use this file except in compliance with the License.
4397  * You may obtain a copy of the License at
4398  *
4399  *      http://www.apache.org/licenses/LICENSE-2.0
4400  *
4401  * Unless required by applicable law or agreed to in writing, software
4402  * distributed under the License is distributed on an "AS IS" BASIS,
4403  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4404  * See the License for the specific language governing permissions and
4405  * limitations under the License.
4406  */
4407 
4408 #ifndef INCLUDE_PERFETTO_EXT_BASE_STRING_UTILS_H_
4409 #define INCLUDE_PERFETTO_EXT_BASE_STRING_UTILS_H_
4410 
4411 #include <string>
4412 #include <vector>
4413 
4414 #include <inttypes.h>
4415 #include <stdlib.h>
4416 
4417 // gen_amalgamated expanded: #include "perfetto/ext/base/optional.h"
4418 // gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
4419 
4420 namespace perfetto {
4421 namespace base {
4422 
4423 std::string QuoteAndEscapeControlCodes(const std::string& raw);
4424 
Lowercase(char c)4425 inline char Lowercase(char c) {
4426   return ('A' <= c && c <= 'Z') ? static_cast<char>(c - ('A' - 'a')) : c;
4427 }
4428 
Uppercase(char c)4429 inline char Uppercase(char c) {
4430   return ('a' <= c && c <= 'z') ? static_cast<char>(c + ('A' - 'a')) : c;
4431 }
4432 
CStringToUInt32(const char * s,int base=10)4433 inline Optional<uint32_t> CStringToUInt32(const char* s, int base = 10) {
4434   char* endptr = nullptr;
4435   auto value = static_cast<uint32_t>(strtoul(s, &endptr, base));
4436   return (*s && !*endptr) ? base::make_optional(value) : base::nullopt;
4437 }
4438 
CStringToInt32(const char * s,int base=10)4439 inline Optional<int32_t> CStringToInt32(const char* s, int base = 10) {
4440   char* endptr = nullptr;
4441   auto value = static_cast<int32_t>(strtol(s, &endptr, base));
4442   return (*s && !*endptr) ? base::make_optional(value) : base::nullopt;
4443 }
4444 
4445 // Note: it saturates to 7fffffffffffffff if parsing a hex number >= 0x8000...
CStringToInt64(const char * s,int base=10)4446 inline Optional<int64_t> CStringToInt64(const char* s, int base = 10) {
4447   char* endptr = nullptr;
4448   auto value = static_cast<int64_t>(strtoll(s, &endptr, base));
4449   return (*s && !*endptr) ? base::make_optional(value) : base::nullopt;
4450 }
4451 
CStringToUInt64(const char * s,int base=10)4452 inline Optional<uint64_t> CStringToUInt64(const char* s, int base = 10) {
4453   char* endptr = nullptr;
4454   auto value = static_cast<uint64_t>(strtoull(s, &endptr, base));
4455   return (*s && !*endptr) ? base::make_optional(value) : base::nullopt;
4456 }
4457 
4458 double StrToD(const char* nptr, char** endptr);
4459 
CStringToDouble(const char * s)4460 inline Optional<double> CStringToDouble(const char* s) {
4461   char* endptr = nullptr;
4462   double value = StrToD(s, &endptr);
4463   Optional<double> result(base::nullopt);
4464   if (*s != '\0' && *endptr == '\0')
4465     result = value;
4466   return result;
4467 }
4468 
StringToUInt32(const std::string & s,int base=10)4469 inline Optional<uint32_t> StringToUInt32(const std::string& s, int base = 10) {
4470   return CStringToUInt32(s.c_str(), base);
4471 }
4472 
StringToInt32(const std::string & s,int base=10)4473 inline Optional<int32_t> StringToInt32(const std::string& s, int base = 10) {
4474   return CStringToInt32(s.c_str(), base);
4475 }
4476 
StringToUInt64(const std::string & s,int base=10)4477 inline Optional<uint64_t> StringToUInt64(const std::string& s, int base = 10) {
4478   return CStringToUInt64(s.c_str(), base);
4479 }
4480 
StringToInt64(const std::string & s,int base=10)4481 inline Optional<int64_t> StringToInt64(const std::string& s, int base = 10) {
4482   return CStringToInt64(s.c_str(), base);
4483 }
4484 
StringToDouble(const std::string & s)4485 inline Optional<double> StringToDouble(const std::string& s) {
4486   return CStringToDouble(s.c_str());
4487 }
4488 
4489 bool StartsWith(const std::string& str, const std::string& prefix);
4490 bool EndsWith(const std::string& str, const std::string& suffix);
4491 bool Contains(const std::string& haystack, const std::string& needle);
4492 bool Contains(const std::string& haystack, char needle);
4493 size_t Find(const StringView& needle, const StringView& haystack);
4494 bool CaseInsensitiveEqual(const std::string& first, const std::string& second);
4495 std::string Join(const std::vector<std::string>& parts,
4496                  const std::string& delim);
4497 std::vector<std::string> SplitString(const std::string& text,
4498                                      const std::string& delimiter);
4499 std::string StripPrefix(const std::string& str, const std::string& prefix);
4500 std::string StripSuffix(const std::string& str, const std::string& suffix);
4501 std::string ToLower(const std::string& str);
4502 std::string ToUpper(const std::string& str);
4503 std::string StripChars(const std::string& str,
4504                        const std::string& chars,
4505                        char replacement);
4506 std::string ToHex(const char* data, size_t size);
ToHex(const std::string & s)4507 inline std::string ToHex(const std::string& s) {
4508   return ToHex(s.c_str(), s.size());
4509 }
4510 std::string IntToHexString(uint32_t number);
4511 std::string Uint64ToHexString(uint64_t number);
4512 std::string Uint64ToHexStringNoPrefix(uint64_t number);
4513 std::string ReplaceAll(std::string str,
4514                        const std::string& to_replace,
4515                        const std::string& replacement);
4516 std::string TrimLeading(const std::string& str);
4517 std::string Base64Encode(const void* raw, size_t size);
4518 
4519 }  // namespace base
4520 }  // namespace perfetto
4521 
4522 #endif  // INCLUDE_PERFETTO_EXT_BASE_STRING_UTILS_H_
4523 /*
4524  * Copyright (C) 2018 The Android Open Source Project
4525  *
4526  * Licensed under the Apache License, Version 2.0 (the "License");
4527  * you may not use this file except in compliance with the License.
4528  * You may obtain a copy of the License at
4529  *
4530  *      http://www.apache.org/licenses/LICENSE-2.0
4531  *
4532  * Unless required by applicable law or agreed to in writing, software
4533  * distributed under the License is distributed on an "AS IS" BASIS,
4534  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4535  * See the License for the specific language governing permissions and
4536  * limitations under the License.
4537  */
4538 
4539 // gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
4540 
4541 #include <inttypes.h>
4542 #include <locale.h>
4543 #include <string.h>
4544 
4545 #if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
4546 #include <xlocale.h>
4547 #endif
4548 
4549 #include <algorithm>
4550 
4551 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
4552 
4553 namespace perfetto {
4554 namespace base {
4555 namespace {
4556 constexpr char kBase64Table[] =
4557     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
4558     "abcdefghijklmnopqrstuvwxyz0123456789+/";
4559 }
4560 
4561 // Locale-independant as possible version of strtod.
StrToD(const char * nptr,char ** endptr)4562 double StrToD(const char* nptr, char** endptr) {
4563 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
4564     PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
4565     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
4566   static auto c_locale = newlocale(LC_ALL, "C", nullptr);
4567   return strtod_l(nptr, endptr, c_locale);
4568 #else
4569   return strtod(nptr, endptr);
4570 #endif
4571 }
4572 
QuoteAndEscapeControlCodes(const std::string & raw)4573 std::string QuoteAndEscapeControlCodes(const std::string& raw) {
4574   std::string ret;
4575   for (auto it = raw.cbegin(); it != raw.cend(); it++) {
4576     switch (*it) {
4577       case '\\':
4578         ret += "\\\\";
4579         break;
4580       case '"':
4581         ret += "\\\"";
4582         break;
4583       case '/':
4584         ret += "\\/";
4585         break;
4586       case '\b':
4587         ret += "\\b";
4588         break;
4589       case '\f':
4590         ret += "\\f";
4591         break;
4592       case '\n':
4593         ret += "\\n";
4594         break;
4595       case '\r':
4596         ret += "\\r";
4597         break;
4598       case '\t':
4599         ret += "\\t";
4600         break;
4601       default:
4602         ret += *it;
4603         break;
4604     }
4605   }
4606   return '"' + ret + '"';
4607 }
4608 
StartsWith(const std::string & str,const std::string & prefix)4609 bool StartsWith(const std::string& str, const std::string& prefix) {
4610   return str.compare(0, prefix.length(), prefix) == 0;
4611 }
4612 
EndsWith(const std::string & str,const std::string & suffix)4613 bool EndsWith(const std::string& str, const std::string& suffix) {
4614   if (suffix.size() > str.size())
4615     return false;
4616   return str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
4617 }
4618 
Contains(const std::string & haystack,const std::string & needle)4619 bool Contains(const std::string& haystack, const std::string& needle) {
4620   return haystack.find(needle) != std::string::npos;
4621 }
4622 
Contains(const std::string & haystack,const char needle)4623 bool Contains(const std::string& haystack, const char needle) {
4624   return haystack.find(needle) != std::string::npos;
4625 }
4626 
Find(const StringView & needle,const StringView & haystack)4627 size_t Find(const StringView& needle, const StringView& haystack) {
4628   if (needle.empty())
4629     return 0;
4630   if (needle.size() > haystack.size())
4631     return std::string::npos;
4632   for (size_t i = 0; i < haystack.size() - (needle.size() - 1); ++i) {
4633     if (strncmp(haystack.data() + i, needle.data(), needle.size()) == 0)
4634       return i;
4635   }
4636   return std::string::npos;
4637 }
4638 
CaseInsensitiveEqual(const std::string & first,const std::string & second)4639 bool CaseInsensitiveEqual(const std::string& first, const std::string& second) {
4640   return first.size() == second.size() &&
4641          std::equal(
4642              first.begin(), first.end(), second.begin(),
4643              [](char a, char b) { return Lowercase(a) == Lowercase(b); });
4644 }
4645 
Join(const std::vector<std::string> & parts,const std::string & delim)4646 std::string Join(const std::vector<std::string>& parts,
4647                  const std::string& delim) {
4648   std::string acc;
4649   for (size_t i = 0; i < parts.size(); ++i) {
4650     acc += parts[i];
4651     if (i + 1 != parts.size()) {
4652       acc += delim;
4653     }
4654   }
4655   return acc;
4656 }
4657 
SplitString(const std::string & text,const std::string & delimiter)4658 std::vector<std::string> SplitString(const std::string& text,
4659                                      const std::string& delimiter) {
4660   PERFETTO_CHECK(!delimiter.empty());
4661 
4662   std::vector<std::string> output;
4663   size_t start = 0;
4664   size_t next;
4665   for (;;) {
4666     next = std::min(text.find(delimiter, start), text.size());
4667     if (next > start)
4668       output.emplace_back(&text[start], next - start);
4669     start = next + delimiter.size();
4670     if (start >= text.size())
4671       break;
4672   }
4673   return output;
4674 }
4675 
StripPrefix(const std::string & str,const std::string & prefix)4676 std::string StripPrefix(const std::string& str, const std::string& prefix) {
4677   return StartsWith(str, prefix) ? str.substr(prefix.size()) : str;
4678 }
4679 
StripSuffix(const std::string & str,const std::string & suffix)4680 std::string StripSuffix(const std::string& str, const std::string& suffix) {
4681   return EndsWith(str, suffix) ? str.substr(0, str.size() - suffix.size())
4682                                : str;
4683 }
4684 
ToUpper(const std::string & str)4685 std::string ToUpper(const std::string& str) {
4686   // Don't use toupper(), it depends on the locale.
4687   std::string res(str);
4688   auto end = res.end();
4689   for (auto c = res.begin(); c != end; ++c)
4690     *c = Uppercase(*c);
4691   return res;
4692 }
4693 
ToLower(const std::string & str)4694 std::string ToLower(const std::string& str) {
4695   // Don't use tolower(), it depends on the locale.
4696   std::string res(str);
4697   auto end = res.end();
4698   for (auto c = res.begin(); c != end; ++c)
4699     *c = Lowercase(*c);
4700   return res;
4701 }
4702 
ToHex(const char * data,size_t size)4703 std::string ToHex(const char* data, size_t size) {
4704   std::string hex(2 * size + 1, 'x');
4705   for (size_t i = 0; i < size; ++i) {
4706     // snprintf prints 3 characters, the two hex digits and a null byte. As we
4707     // write left to right, we keep overwriting the nullbytes, except for the
4708     // last call to snprintf.
4709     snprintf(&(hex[2 * i]), 3, "%02hhx", data[i]);
4710   }
4711   // Remove the trailing nullbyte produced by the last snprintf.
4712   hex.resize(2 * size);
4713   return hex;
4714 }
4715 
IntToHexString(uint32_t number)4716 std::string IntToHexString(uint32_t number) {
4717   size_t max_size = 11;  // Max uint32 is 0xFFFFFFFF + 1 for null byte.
4718   std::string buf;
4719   buf.resize(max_size);
4720   auto final_size = snprintf(&buf[0], max_size, "0x%02x", number);
4721   PERFETTO_DCHECK(final_size >= 0);
4722   buf.resize(static_cast<size_t>(final_size));  // Cuts off the final null byte.
4723   return buf;
4724 }
4725 
Uint64ToHexString(uint64_t number)4726 std::string Uint64ToHexString(uint64_t number) {
4727   return "0x" + Uint64ToHexStringNoPrefix(number);
4728 }
4729 
Uint64ToHexStringNoPrefix(uint64_t number)4730 std::string Uint64ToHexStringNoPrefix(uint64_t number) {
4731   size_t max_size = 17;  // Max uint64 is FFFFFFFFFFFFFFFF + 1 for null byte.
4732   std::string buf;
4733   buf.resize(max_size);
4734   auto final_size = snprintf(&buf[0], max_size, "%" PRIx64 "", number);
4735   PERFETTO_DCHECK(final_size >= 0);
4736   buf.resize(static_cast<size_t>(final_size));  // Cuts off the final null byte.
4737   return buf;
4738 }
4739 
StripChars(const std::string & str,const std::string & chars,char replacement)4740 std::string StripChars(const std::string& str,
4741                        const std::string& chars,
4742                        char replacement) {
4743   std::string res(str);
4744   const char* start = res.c_str();
4745   const char* remove = chars.c_str();
4746   for (const char* c = strpbrk(start, remove); c; c = strpbrk(c + 1, remove))
4747     res[static_cast<uintptr_t>(c - start)] = replacement;
4748   return res;
4749 }
4750 
ReplaceAll(std::string str,const std::string & to_replace,const std::string & replacement)4751 std::string ReplaceAll(std::string str,
4752                        const std::string& to_replace,
4753                        const std::string& replacement) {
4754   PERFETTO_CHECK(!to_replace.empty());
4755   size_t pos = 0;
4756   while ((pos = str.find(to_replace, pos)) != std::string::npos) {
4757     str.replace(pos, to_replace.length(), replacement);
4758     pos += replacement.length();
4759   }
4760   return str;
4761 }
4762 
TrimLeading(const std::string & str)4763 std::string TrimLeading(const std::string& str) {
4764   size_t idx = str.find_first_not_of(' ');
4765   return idx == std::string::npos ? str : str.substr(idx);
4766 }
4767 
Base64Encode(const void * raw,size_t size)4768 std::string Base64Encode(const void* raw, size_t size) {
4769   // The following three cases are based on the tables in the example
4770   // section in https://en.wikipedia.org/wiki/Base64. We process three
4771   // input bytes at a time, emitting 4 output bytes at a time.
4772   const uint8_t* ptr = static_cast<const uint8_t*>(raw);
4773   size_t ii = 0;
4774 
4775   std::string out;
4776   out.reserve((size + 2) * 4 / 3);
4777 
4778   // While possible, process three input bytes.
4779   for (; ii + 3 <= size; ii += 3) {
4780     uint32_t twentyfour_bits =
4781         (uint32_t(ptr[ii]) << 16) | (uint32_t(ptr[ii + 1]) << 8) | ptr[ii + 2];
4782     out.push_back(kBase64Table[(twentyfour_bits >> 18)]);
4783     out.push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]);
4784     out.push_back(kBase64Table[(twentyfour_bits >> 6) & 0x3f]);
4785     out.push_back(kBase64Table[twentyfour_bits & 0x3f]);
4786   }
4787   if (ii + 2 <= size) {  // Process two input bytes.
4788     uint32_t twentyfour_bits =
4789         (uint32_t(ptr[ii]) << 16) | (uint32_t(ptr[ii + 1]) << 8);
4790     out.push_back(kBase64Table[(twentyfour_bits >> 18)]);
4791     out.push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]);
4792     out.push_back(kBase64Table[(twentyfour_bits >> 6) & 0x3f]);
4793     out.push_back('=');  // Emit padding.
4794     return out;
4795   }
4796   if (ii + 1 <= size) {  // Process a single input byte.
4797     uint32_t twentyfour_bits = (uint32_t(ptr[ii]) << 16);
4798     out.push_back(kBase64Table[(twentyfour_bits >> 18)]);
4799     out.push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]);
4800     out.push_back('=');  // Emit padding.
4801     out.push_back('=');  // Emit padding.
4802   }
4803   return out;
4804 }
4805 
4806 }  // namespace base
4807 }  // namespace perfetto
4808 // gen_amalgamated begin source: src/base/string_view.cc
4809 /*
4810  * Copyright (C) 2019 The Android Open Source Project
4811  *
4812  * Licensed under the Apache License, Version 2.0 (the "License");
4813  * you may not use this file except in compliance with the License.
4814  * You may obtain a copy of the License at
4815  *
4816  *      http://www.apache.org/licenses/LICENSE-2.0
4817  *
4818  * Unless required by applicable law or agreed to in writing, software
4819  * distributed under the License is distributed on an "AS IS" BASIS,
4820  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4821  * See the License for the specific language governing permissions and
4822  * limitations under the License.
4823  */
4824 
4825 // gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
4826 
4827 namespace perfetto {
4828 namespace base {
4829 
4830 // static
4831 constexpr size_t StringView::npos;
4832 
4833 }  // namespace base
4834 }  // namespace perfetto
4835 // gen_amalgamated begin source: src/base/temp_file.cc
4836 // gen_amalgamated begin header: include/perfetto/ext/base/temp_file.h
4837 /*
4838  * Copyright (C) 2018 The Android Open Source Project
4839  *
4840  * Licensed under the Apache License, Version 2.0 (the "License");
4841  * you may not use this file except in compliance with the License.
4842  * You may obtain a copy of the License at
4843  *
4844  *      http://www.apache.org/licenses/LICENSE-2.0
4845  *
4846  * Unless required by applicable law or agreed to in writing, software
4847  * distributed under the License is distributed on an "AS IS" BASIS,
4848  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4849  * See the License for the specific language governing permissions and
4850  * limitations under the License.
4851  */
4852 
4853 #ifndef INCLUDE_PERFETTO_EXT_BASE_TEMP_FILE_H_
4854 #define INCLUDE_PERFETTO_EXT_BASE_TEMP_FILE_H_
4855 
4856 #include <string>
4857 
4858 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
4859 
4860 namespace perfetto {
4861 namespace base {
4862 
4863 std::string GetSysTempDir();
4864 
4865 class TempFile {
4866  public:
4867   static TempFile CreateUnlinked();
4868   static TempFile Create();
4869 
4870   TempFile(TempFile&&) noexcept;
4871   TempFile& operator=(TempFile&&);
4872   ~TempFile();
4873 
path() const4874   const std::string& path() const { return path_; }
fd() const4875   int fd() const { return *fd_; }
operator *() const4876   int operator*() const { return *fd_; }
4877 
4878   // Unlinks the file from the filesystem but keeps the fd() open.
4879   // It is safe to call this multiple times.
4880   void Unlink();
4881 
4882   // Releases the underlying file descriptor. Will unlink the file from the
4883   // filesystem if it was created via CreateUnlinked().
4884   ScopedFile ReleaseFD();
4885 
4886  private:
4887   TempFile();
4888   TempFile(const TempFile&) = delete;
4889   TempFile& operator=(const TempFile&) = delete;
4890 
4891   ScopedFile fd_;
4892   std::string path_;
4893 };
4894 
4895 class TempDir {
4896  public:
4897   static TempDir Create();
4898 
4899   TempDir(TempDir&&) noexcept;
4900   TempDir& operator=(TempDir&&);
4901   ~TempDir();
4902 
path() const4903   const std::string& path() const { return path_; }
4904 
4905  private:
4906   TempDir();
4907   TempDir(const TempDir&) = delete;
4908   TempDir& operator=(const TempDir&) = delete;
4909 
4910   std::string path_;
4911 };
4912 
4913 }  // namespace base
4914 }  // namespace perfetto
4915 
4916 #endif  // INCLUDE_PERFETTO_EXT_BASE_TEMP_FILE_H_
4917 /*
4918  * Copyright (C) 2018 The Android Open Source Project
4919  *
4920  * Licensed under the Apache License, Version 2.0 (the "License");
4921  * you may not use this file except in compliance with the License.
4922  * You may obtain a copy of the License at
4923  *
4924  *      http://www.apache.org/licenses/LICENSE-2.0
4925  *
4926  * Unless required by applicable law or agreed to in writing, software
4927  * distributed under the License is distributed on an "AS IS" BASIS,
4928  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4929  * See the License for the specific language governing permissions and
4930  * limitations under the License.
4931  */
4932 
4933 // gen_amalgamated expanded: #include "perfetto/ext/base/temp_file.h"
4934 
4935 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
4936 
4937 #include <stdio.h>
4938 #include <stdlib.h>
4939 #include <string.h>
4940 
4941 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4942 #include <Windows.h>
4943 #include <direct.h>
4944 #include <fileapi.h>
4945 #include <io.h>
4946 #else
4947 #include <unistd.h>
4948 #endif
4949 
4950 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
4951 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
4952 // gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
4953 
4954 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4955 namespace {
GetTempName()4956 std::string GetTempName() {
4957   char name[] = "perfetto-XXXXXX";
4958   PERFETTO_CHECK(_mktemp_s(name, sizeof(name)) == 0);
4959   return name;
4960 }
4961 }  // namespace
4962 #endif
4963 
4964 namespace perfetto {
4965 namespace base {
4966 
GetSysTempDir()4967 std::string GetSysTempDir() {
4968   const char* tmpdir = nullptr;
4969 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4970   if ((tmpdir = getenv("TMP")))
4971     return tmpdir;
4972   if ((tmpdir = getenv("TEMP")))
4973     return tmpdir;
4974   return "C:\\TEMP";
4975 #else
4976   if ((tmpdir = getenv("TMPDIR")))
4977     return base::StripSuffix(tmpdir, "/");
4978 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
4979   return "/data/local/tmp";
4980 #else
4981   return "/tmp";
4982 #endif  // !OS_ANDROID
4983 #endif  // !OS_WIN
4984 }
4985 
4986 // static
Create()4987 TempFile TempFile::Create() {
4988   TempFile temp_file;
4989 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4990   temp_file.path_ = GetSysTempDir() + "\\" + GetTempName();
4991   // Several tests want to read-back the temp file while still open. On Windows,
4992   // that requires FILE_SHARE_READ. FILE_SHARE_READ is NOT settable when using
4993   // the POSIX-compat equivalent function _open(). Hence the CreateFileA +
4994   // _open_osfhandle dance here.
4995   HANDLE h =
4996       ::CreateFileA(temp_file.path_.c_str(), GENERIC_READ | GENERIC_WRITE,
4997                     FILE_SHARE_DELETE | FILE_SHARE_READ, nullptr, CREATE_ALWAYS,
4998                     FILE_ATTRIBUTE_TEMPORARY, nullptr);
4999   PERFETTO_CHECK(PlatformHandleChecker::IsValid(h));
5000   // According to MSDN, when using _open_osfhandle the caller must not call
5001   // CloseHandle(). Ownership is moved to the file descriptor, which then needs
5002   // to be closed with just with _close().
5003   temp_file.fd_.reset(_open_osfhandle(reinterpret_cast<intptr_t>(h), 0));
5004 #else
5005   temp_file.path_ = GetSysTempDir() + "/perfetto-XXXXXXXX";
5006   temp_file.fd_.reset(mkstemp(&temp_file.path_[0]));
5007 #endif
5008   if (PERFETTO_UNLIKELY(!temp_file.fd_)) {
5009     PERFETTO_FATAL("Could not create temp file %s", temp_file.path_.c_str());
5010   }
5011   return temp_file;
5012 }
5013 
5014 // static
CreateUnlinked()5015 TempFile TempFile::CreateUnlinked() {
5016   TempFile temp_file = TempFile::Create();
5017   temp_file.Unlink();
5018   return temp_file;
5019 }
5020 
5021 TempFile::TempFile() = default;
5022 
~TempFile()5023 TempFile::~TempFile() {
5024   Unlink();
5025 }
5026 
ReleaseFD()5027 ScopedFile TempFile::ReleaseFD() {
5028   Unlink();
5029   return std::move(fd_);
5030 }
5031 
Unlink()5032 void TempFile::Unlink() {
5033   if (path_.empty())
5034     return;
5035 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5036   // If the FD is still open DeleteFile will mark the file as pending deletion
5037   // and delete it only when the process exists.
5038   PERFETTO_CHECK(DeleteFileA(path_.c_str()));
5039 #else
5040   PERFETTO_CHECK(unlink(path_.c_str()) == 0);
5041 #endif
5042   path_.clear();
5043 }
5044 
5045 TempFile::TempFile(TempFile&&) noexcept = default;
5046 TempFile& TempFile::operator=(TempFile&&) = default;
5047 
5048 // static
Create()5049 TempDir TempDir::Create() {
5050   TempDir temp_dir;
5051 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5052   temp_dir.path_ = GetSysTempDir() + "\\" + GetTempName();
5053   PERFETTO_CHECK(_mkdir(temp_dir.path_.c_str()) == 0);
5054 #else
5055   temp_dir.path_ = GetSysTempDir() + "/perfetto-XXXXXXXX";
5056   PERFETTO_CHECK(mkdtemp(&temp_dir.path_[0]));
5057 #endif
5058   return temp_dir;
5059 }
5060 
5061 TempDir::TempDir() = default;
5062 TempDir::TempDir(TempDir&&) noexcept = default;
5063 TempDir& TempDir::operator=(TempDir&&) = default;
5064 
~TempDir()5065 TempDir::~TempDir() {
5066   if (path_.empty())
5067     return;  // For objects that get std::move()d.
5068   PERFETTO_CHECK(Rmdir(path_));
5069 }
5070 
5071 }  // namespace base
5072 }  // namespace perfetto
5073 // gen_amalgamated begin source: src/base/thread_checker.cc
5074 /*
5075  * Copyright (C) 2017 The Android Open Source Project
5076  *
5077  * Licensed under the Apache License, Version 2.0 (the "License");
5078  * you may not use this file except in compliance with the License.
5079  * You may obtain a copy of the License at
5080  *
5081  *      http://www.apache.org/licenses/LICENSE-2.0
5082  *
5083  * Unless required by applicable law or agreed to in writing, software
5084  * distributed under the License is distributed on an "AS IS" BASIS,
5085  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5086  * See the License for the specific language governing permissions and
5087  * limitations under the License.
5088  */
5089 
5090 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
5091 
5092 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5093 #include <Windows.h>
5094 #endif
5095 
5096 namespace perfetto {
5097 namespace base {
5098 
5099 namespace {
5100 constexpr ThreadID kDetached{};
5101 
CurrentThreadId()5102 ThreadID CurrentThreadId() {
5103 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5104   return ::GetCurrentThreadId();
5105 #else
5106   return pthread_self();
5107 #endif
5108 }
5109 }  // namespace
5110 
ThreadChecker()5111 ThreadChecker::ThreadChecker() {
5112   thread_id_.store(CurrentThreadId());
5113 }
5114 
5115 ThreadChecker::~ThreadChecker() = default;
5116 
ThreadChecker(const ThreadChecker & other)5117 ThreadChecker::ThreadChecker(const ThreadChecker& other) {
5118   thread_id_ = other.thread_id_.load();
5119 }
5120 
operator =(const ThreadChecker & other)5121 ThreadChecker& ThreadChecker::operator=(const ThreadChecker& other) {
5122   thread_id_ = other.thread_id_.load();
5123   return *this;
5124 }
5125 
CalledOnValidThread() const5126 bool ThreadChecker::CalledOnValidThread() const {
5127   auto self = CurrentThreadId();
5128 
5129   // Will re-attach if previously detached using DetachFromThread().
5130   auto prev_value = kDetached;
5131   if (thread_id_.compare_exchange_strong(prev_value, self))
5132     return true;
5133   return prev_value == self;
5134 }
5135 
DetachFromThread()5136 void ThreadChecker::DetachFromThread() {
5137   thread_id_.store(kDetached);
5138 }
5139 
5140 }  // namespace base
5141 }  // namespace perfetto
5142 // gen_amalgamated begin source: src/base/time.cc
5143 /*
5144  * Copyright (C) 2018 The Android Open Source Project
5145  *
5146  * Licensed under the Apache License, Version 2.0 (the "License");
5147  * you may not use this file except in compliance with the License.
5148  * You may obtain a copy of the License at
5149  *
5150  *      http://www.apache.org/licenses/LICENSE-2.0
5151  *
5152  * Unless required by applicable law or agreed to in writing, software
5153  * distributed under the License is distributed on an "AS IS" BASIS,
5154  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5155  * See the License for the specific language governing permissions and
5156  * limitations under the License.
5157  */
5158 
5159 // gen_amalgamated expanded: #include "perfetto/base/time.h"
5160 
5161 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
5162 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
5163 
5164 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5165 #include <Windows.h>
5166 #else
5167 #include <unistd.h>
5168 #endif
5169 
5170 namespace perfetto {
5171 namespace base {
5172 
5173 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5174 
GetWallTimeNs()5175 TimeNanos GetWallTimeNs() {
5176   LARGE_INTEGER freq;
5177   ::QueryPerformanceFrequency(&freq);
5178   LARGE_INTEGER counter;
5179   ::QueryPerformanceCounter(&counter);
5180   double elapsed_nanoseconds = (1e9 * static_cast<double>(counter.QuadPart)) /
5181                                static_cast<double>(freq.QuadPart);
5182   return TimeNanos(static_cast<uint64_t>(elapsed_nanoseconds));
5183 }
5184 
GetThreadCPUTimeNs()5185 TimeNanos GetThreadCPUTimeNs() {
5186   FILETIME dummy, kernel_ftime, user_ftime;
5187   ::GetThreadTimes(GetCurrentThread(), &dummy, &dummy, &kernel_ftime,
5188                    &user_ftime);
5189   uint64_t kernel_time = kernel_ftime.dwHighDateTime * 0x100000000 +
5190                          kernel_ftime.dwLowDateTime;
5191   uint64_t user_time = user_ftime.dwHighDateTime * 0x100000000 +
5192                        user_ftime.dwLowDateTime;
5193 
5194   return TimeNanos((kernel_time + user_time) * 100);
5195 }
5196 
SleepMicroseconds(unsigned interval_us)5197 void SleepMicroseconds(unsigned interval_us) {
5198   // The Windows Sleep function takes a millisecond count. Round up so that
5199   // short sleeps don't turn into a busy wait. Note that the sleep granularity
5200   // on Windows can dynamically vary from 1 ms to ~16 ms, so don't count on this
5201   // being a short sleep.
5202   ::Sleep(static_cast<DWORD>((interval_us + 999) / 1000));
5203 }
5204 
5205 #else  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5206 
5207 void SleepMicroseconds(unsigned interval_us) {
5208   ::usleep(static_cast<useconds_t>(interval_us));
5209 }
5210 
5211 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5212 
GetTimeFmt(const std::string & fmt)5213 std::string GetTimeFmt(const std::string& fmt) {
5214   time_t raw_time;
5215   time(&raw_time);
5216   struct tm* local_tm;
5217   local_tm = localtime(&raw_time);
5218   char buf[128];
5219   PERFETTO_CHECK(strftime(buf, 80, fmt.c_str(), local_tm) > 0);
5220   return buf;
5221 }
5222 
5223 }  // namespace base
5224 }  // namespace perfetto
5225 // gen_amalgamated begin source: src/base/utils.cc
5226 /*
5227  * Copyright (C) 2020 The Android Open Source Project
5228  *
5229  * Licensed under the Apache License, Version 2.0 (the "License");
5230  * you may not use this file except in compliance with the License.
5231  * You may obtain a copy of the License at
5232  *
5233  *      http://www.apache.org/licenses/LICENSE-2.0
5234  *
5235  * Unless required by applicable law or agreed to in writing, software
5236  * distributed under the License is distributed on an "AS IS" BASIS,
5237  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5238  * See the License for the specific language governing permissions and
5239  * limitations under the License.
5240  */
5241 
5242 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
5243 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
5244 
5245 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
5246 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
5247 
5248 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
5249     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
5250     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
5251 #include <unistd.h>  // For getpagesize() and geteuid() & fork()
5252 #endif
5253 
5254 #if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
5255 #include <mach/vm_page_size.h>
5256 #endif
5257 
5258 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
5259 #include <dlfcn.h>
5260 #include <malloc.h>
5261 
5262 #ifdef M_PURGE
5263 #define PERFETTO_M_PURGE M_PURGE
5264 #else
5265 // Only available in in-tree builds and on newer SDKs.
5266 #define PERFETTO_M_PURGE -101
5267 #endif
5268 
5269 namespace {
5270 extern "C" {
5271 using MalloptType = void (*)(int, int);
5272 }
5273 }  // namespace
5274 #endif  // OS_ANDROID
5275 
5276 namespace perfetto {
5277 namespace base {
5278 
MaybeReleaseAllocatorMemToOS()5279 void MaybeReleaseAllocatorMemToOS() {
5280 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
5281   // mallopt() on Android requires SDK level 26. Many targets and embedders
5282   // still depend on a lower SDK level. Given mallopt() is a quite simple API,
5283   // use reflection to do this rather than bumping the SDK level for all
5284   // embedders. This keeps the behavior of standalone builds aligned with
5285   // in-tree builds.
5286   static MalloptType mallopt_fn =
5287       reinterpret_cast<MalloptType>(dlsym(RTLD_DEFAULT, "mallopt"));
5288   if (!mallopt_fn)
5289     return;
5290   mallopt_fn(PERFETTO_M_PURGE, 0);
5291 #endif
5292 }
5293 
GetSysPageSize()5294 uint32_t GetSysPageSize() {
5295   ignore_result(kPageSize);  // Just to keep the amalgamated build happy.
5296 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
5297     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
5298   static std::atomic<uint32_t> page_size{0};
5299   // This function might be called in hot paths. Avoid calling getpagesize() all
5300   // the times, in many implementations getpagesize() calls sysconf() which is
5301   // not cheap.
5302   uint32_t cached_value = page_size.load(std::memory_order_relaxed);
5303   if (PERFETTO_UNLIKELY(cached_value == 0)) {
5304     cached_value = static_cast<uint32_t>(getpagesize());
5305     page_size.store(cached_value, std::memory_order_relaxed);
5306   }
5307   return cached_value;
5308 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
5309   return static_cast<uint32_t>(vm_page_size);
5310 #else
5311   return 4096;
5312 #endif
5313 }
5314 
GetCurrentUserId()5315 uid_t GetCurrentUserId() {
5316 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
5317     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
5318     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
5319   return geteuid();
5320 #else
5321   // TODO(primiano): On Windows we could hash the current user SID and derive a
5322   // numeric user id [1]. It is not clear whether we need that. Right now that
5323   // would not bring any benefit. Returning 0 unil we can prove we need it.
5324   // [1]:https://android-review.googlesource.com/c/platform/external/perfetto/+/1513879/25/src/base/utils.cc
5325   return 0;
5326 #endif
5327 }
5328 
SetEnv(const std::string & key,const std::string & value)5329 void SetEnv(const std::string& key, const std::string& value) {
5330 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5331   PERFETTO_CHECK(::_putenv_s(key.c_str(), value.c_str()) == 0);
5332 #else
5333   PERFETTO_CHECK(::setenv(key.c_str(), value.c_str(), /*overwrite=*/true) == 0);
5334 #endif
5335 }
5336 
Daemonize()5337 void Daemonize() {
5338    #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
5339        PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
5340        PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
5341       pid_t pid;
5342       switch (pid = fork()) {
5343         case -1:
5344           PERFETTO_FATAL("fork");
5345         case 0: {
5346           PERFETTO_CHECK(setsid() != -1);
5347           base::ignore_result(chdir("/"));
5348           base::ScopedFile null = base::OpenFile("/dev/null", O_RDONLY);
5349           PERFETTO_CHECK(null);
5350           PERFETTO_CHECK(dup2(*null, STDIN_FILENO) != -1);
5351           PERFETTO_CHECK(dup2(*null, STDOUT_FILENO) != -1);
5352           PERFETTO_CHECK(dup2(*null, STDERR_FILENO) != -1);
5353           // Do not accidentally close stdin/stdout/stderr.
5354           if (*null <= 2)
5355             null.release();
5356           break;
5357         }
5358         default:
5359           printf("%d\n", pid);
5360           exit(0);
5361       }
5362   #else
5363     // Avoid -Wunreachable warnings.
5364     if (reinterpret_cast<intptr_t>(&Daemonize) != 16)
5365       PERFETTO_FATAL("--background is only supported on Linux/Android/Mac");
5366   #endif  // OS_WIN
5367 }
5368 
5369 }  // namespace base
5370 }  // namespace perfetto
5371 // gen_amalgamated begin source: src/base/uuid.cc
5372 // gen_amalgamated begin header: include/perfetto/ext/base/uuid.h
5373 /*
5374  * Copyright (C) 2019 The Android Open Source Project
5375  *
5376  * Licensed under the Apache License, Version 2.0 (the "License");
5377  * you may not use this file except in compliance with the License.
5378  * You may obtain a copy of the License at
5379  *
5380  *      http://www.apache.org/licenses/LICENSE-2.0
5381  *
5382  * Unless required by applicable law or agreed to in writing, software
5383  * distributed under the License is distributed on an "AS IS" BASIS,
5384  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5385  * See the License for the specific language governing permissions and
5386  * limitations under the License.
5387  */
5388 
5389 #ifndef INCLUDE_PERFETTO_EXT_BASE_UUID_H_
5390 #define INCLUDE_PERFETTO_EXT_BASE_UUID_H_
5391 
5392 #include <array>
5393 #include <string>
5394 
5395 // gen_amalgamated expanded: #include "perfetto/ext/base/optional.h"
5396 
5397 namespace perfetto {
5398 namespace base {
5399 
5400 class Uuid {
5401  public:
5402   explicit Uuid(const std::string& s);
5403   explicit Uuid(int64_t lsb, int64_t msb);
5404   Uuid();
5405 
data()5406   std::array<uint8_t, 16>* data() { return &data_; }
data() const5407   const std::array<uint8_t, 16>* data() const { return &data_; }
5408 
operator ==(const Uuid & other) const5409   bool operator==(const Uuid& other) const { return data_ == other.data_; }
5410 
operator !=(const Uuid & other) const5411   bool operator!=(const Uuid& other) const { return !(*this == other); }
5412 
msb() const5413   int64_t msb() const {
5414     int64_t result;
5415     memcpy(&result, data_.data() + 8, 8);
5416     return result;
5417   }
5418 
lsb() const5419   int64_t lsb() const {
5420     int64_t result;
5421     memcpy(&result, data_.data(), 8);
5422     return result;
5423   }
5424 
set_lsb_msb(int64_t lsb,int64_t msb)5425   void set_lsb_msb(int64_t lsb, int64_t msb) {
5426     set_lsb(lsb);
5427     set_msb(msb);
5428   }
set_msb(int64_t msb)5429   void set_msb(int64_t msb) { memcpy(data_.data() + 8, &msb, 8); }
set_lsb(int64_t lsb)5430   void set_lsb(int64_t lsb) { memcpy(data_.data(), &lsb, 8); }
5431 
5432   std::string ToString() const;
5433   std::string ToPrettyString() const;
5434 
5435  private:
5436   std::array<uint8_t, 16> data_{};
5437 };
5438 
5439 Uuid Uuidv4();
5440 
5441 }  // namespace base
5442 }  // namespace perfetto
5443 
5444 #endif  // INCLUDE_PERFETTO_EXT_BASE_UUID_H_
5445 /*
5446  * Copyright (C) 2019 The Android Open Source Project
5447  *
5448  * Licensed under the Apache License, Version 2.0 (the "License");
5449  * you may not use this file except in compliance with the License.
5450  * You may obtain a copy of the License at
5451  *
5452  *      http://www.apache.org/licenses/LICENSE-2.0
5453  *
5454  * Unless required by applicable law or agreed to in writing, software
5455  * distributed under the License is distributed on an "AS IS" BASIS,
5456  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5457  * See the License for the specific language governing permissions and
5458  * limitations under the License.
5459  */
5460 
5461 // gen_amalgamated expanded: #include "perfetto/ext/base/uuid.h"
5462 
5463 #include <random>
5464 
5465 // gen_amalgamated expanded: #include "perfetto/base/time.h"
5466 
5467 namespace perfetto {
5468 namespace base {
5469 namespace {
5470 
5471 constexpr char kHexmap[] = {'0', '1', '2', '3', '4', '5', '6', '7',
5472                             '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
5473 }  // namespace
5474 
5475 // See https://www.ietf.org/rfc/rfc4122.txt
Uuidv4()5476 Uuid Uuidv4() {
5477   static std::minstd_rand rng(static_cast<uint32_t>(GetBootTimeNs().count()));
5478   Uuid uuid;
5479   auto& data = *uuid.data();
5480 
5481   for (size_t i = 0; i < 16; ++i)
5482     data[i] = static_cast<uint8_t>(rng());
5483 
5484   // version:
5485   data[6] = (data[6] & 0x0f) | 0x40;
5486   // clock_seq_hi_and_reserved:
5487   data[8] = (data[8] & 0x3f) | 0x80;
5488 
5489   return uuid;
5490 }
5491 
Uuid()5492 Uuid::Uuid() {}
5493 
Uuid(const std::string & s)5494 Uuid::Uuid(const std::string& s) {
5495   PERFETTO_CHECK(s.size() == data_.size());
5496   memcpy(data_.data(), s.data(), s.size());
5497 }
5498 
Uuid(int64_t lsb,int64_t msb)5499 Uuid::Uuid(int64_t lsb, int64_t msb) {
5500   set_lsb_msb(lsb, msb);
5501 }
5502 
ToString() const5503 std::string Uuid::ToString() const {
5504   return std::string(reinterpret_cast<const char*>(data_.data()), data_.size());
5505 }
5506 
ToPrettyString() const5507 std::string Uuid::ToPrettyString() const {
5508   std::string s(data_.size() * 2 + 4, '-');
5509   // Format is 123e4567-e89b-12d3-a456-426655443322.
5510   size_t j = 0;
5511   for (size_t i = 0; i < data_.size(); ++i) {
5512     if (i == 4 || i == 6 || i == 8 || i == 10)
5513       j++;
5514     s[2 * i + j] = kHexmap[(data_[data_.size() - i - 1] & 0xf0) >> 4];
5515     s[2 * i + 1 + j] = kHexmap[(data_[data_.size() - i - 1] & 0x0f)];
5516   }
5517   return s;
5518 }
5519 
5520 }  // namespace base
5521 }  // namespace perfetto
5522 // gen_amalgamated begin source: src/base/version.cc
5523 // gen_amalgamated begin header: include/perfetto/ext/base/version.h
5524 /*
5525  * Copyright (C) 2020 The Android Open Source Project
5526  *
5527  * Licensed under the Apache License, Version 2.0 (the "License");
5528  * you may not use this file except in compliance with the License.
5529  * You may obtain a copy of the License at
5530  *
5531  *      http://www.apache.org/licenses/LICENSE-2.0
5532  *
5533  * Unless required by applicable law or agreed to in writing, software
5534  * distributed under the License is distributed on an "AS IS" BASIS,
5535  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5536  * See the License for the specific language governing permissions and
5537  * limitations under the License.
5538  */
5539 
5540 #ifndef INCLUDE_PERFETTO_EXT_BASE_VERSION_H_
5541 #define INCLUDE_PERFETTO_EXT_BASE_VERSION_H_
5542 
5543 namespace perfetto {
5544 namespace base {
5545 
5546 // The returned pointer is a static string is safe to pass around.
5547 const char* GetVersionString();
5548 
5549 }  // namespace base
5550 }  // namespace perfetto
5551 
5552 #endif  // INCLUDE_PERFETTO_EXT_BASE_VERSION_H_
5553 // gen_amalgamated begin header: gen/perfetto_version.gen.h
5554 // Generated by write_version_header.py
5555 
5556 #ifndef GEN_PERFETTO_VERSION_GEN_H_
5557 #define GEN_PERFETTO_VERSION_GEN_H_
5558 
5559 #define PERFETTO_VERSION_STRING() "v15.0"
5560 #define PERFETTO_VERSION_SCM_REVISION() "f69a7701253a1c934595a31c581465a1acb0af80"
5561 
5562 #endif  // GEN_PERFETTO_VERSION_GEN_H_
5563 /*
5564  * Copyright (C) 2020 The Android Open Source Project
5565  *
5566  * Licensed under the Apache License, Version 2.0 (the "License");
5567  * you may not use this file except in compliance with the License.
5568  * You may obtain a copy of the License at
5569  *
5570  *      http://www.apache.org/licenses/LICENSE-2.0
5571  *
5572  * Unless required by applicable law or agreed to in writing, software
5573  * distributed under the License is distributed on an "AS IS" BASIS,
5574  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5575  * See the License for the specific language governing permissions and
5576  * limitations under the License.
5577  */
5578 
5579 // gen_amalgamated expanded: #include "perfetto/ext/base/version.h"
5580 
5581 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
5582 
5583 #include <stdio.h>
5584 
5585 #if PERFETTO_BUILDFLAG(PERFETTO_VERSION_GEN)
5586 // gen_amalgamated expanded: #include "perfetto_version.gen.h"
5587 #else
5588 #define PERFETTO_VERSION_STRING() "v0.0"
5589 #define PERFETTO_VERSION_SCM_REVISION() "unknown"
5590 #endif
5591 
5592 namespace perfetto {
5593 namespace base {
5594 
GetVersionString()5595 const char* GetVersionString() {
5596   static const char* version_str = [] {
5597     static constexpr size_t kMaxLen = 256;
5598     char* version = new char[kMaxLen + 1];
5599     snprintf(version, kMaxLen, "Perfetto %s (%s)", PERFETTO_VERSION_STRING(),
5600              PERFETTO_VERSION_SCM_REVISION());
5601     return version;
5602   }();
5603   return version_str;
5604 }
5605 
5606 }  // namespace base
5607 }  // namespace perfetto
5608 // gen_amalgamated begin source: src/base/virtual_destructors.cc
5609 /*
5610  * Copyright (C) 2017 The Android Open Source Project
5611  *
5612  * Licensed under the Apache License, Version 2.0 (the "License");
5613  * you may not use this file except in compliance with the License.
5614  * You may obtain a copy of the License at
5615  *
5616  *      http://www.apache.org/licenses/LICENSE-2.0
5617  *
5618  * Unless required by applicable law or agreed to in writing, software
5619  * distributed under the License is distributed on an "AS IS" BASIS,
5620  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5621  * See the License for the specific language governing permissions and
5622  * limitations under the License.
5623  */
5624 
5625 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
5626 
5627 // This translation unit contains the definitions for the destructor of pure
5628 // virtual interfaces for the current build target. The alternative would be
5629 // introducing a one-liner .cc file for each pure virtual interface, which is
5630 // overkill. This is for compliance with -Wweak-vtables.
5631 
5632 namespace perfetto {
5633 namespace base {
5634 
5635 TaskRunner::~TaskRunner() = default;
5636 
5637 }  // namespace base
5638 }  // namespace perfetto
5639 // gen_amalgamated begin source: src/base/waitable_event.cc
5640 // gen_amalgamated begin header: include/perfetto/ext/base/waitable_event.h
5641 /*
5642  * Copyright (C) 2019 The Android Open Source Project
5643  *
5644  * Licensed under the Apache License, Version 2.0 (the "License");
5645  * you may not use this file except in compliance with the License.
5646  * You may obtain a copy of the License at
5647  *
5648  *      http://www.apache.org/licenses/LICENSE-2.0
5649  *
5650  * Unless required by applicable law or agreed to in writing, software
5651  * distributed under the License is distributed on an "AS IS" BASIS,
5652  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5653  * See the License for the specific language governing permissions and
5654  * limitations under the License.
5655  */
5656 
5657 #ifndef INCLUDE_PERFETTO_EXT_BASE_WAITABLE_EVENT_H_
5658 #define INCLUDE_PERFETTO_EXT_BASE_WAITABLE_EVENT_H_
5659 
5660 #include <condition_variable>
5661 #include <mutex>
5662 
5663 namespace perfetto {
5664 namespace base {
5665 
5666 // A waitable event for cross-thread synchronization.
5667 // All methods on this class can be called from any thread.
5668 class WaitableEvent {
5669  public:
5670   WaitableEvent();
5671   ~WaitableEvent();
5672   WaitableEvent(const WaitableEvent&) = delete;
5673   WaitableEvent operator=(const WaitableEvent&) = delete;
5674 
5675   // Synchronously block until the event is notified.
5676   void Wait();
5677 
5678   // Signal the event, waking up blocked waiters.
5679   void Notify();
5680 
5681  private:
5682   std::mutex mutex_;
5683   std::condition_variable event_;
5684   bool notified_ = false;
5685 };
5686 
5687 }  // namespace base
5688 }  // namespace perfetto
5689 
5690 #endif  // INCLUDE_PERFETTO_EXT_BASE_WAITABLE_EVENT_H_
5691 /*
5692  * Copyright (C) 2019 The Android Open Source Project
5693  *
5694  * Licensed under the Apache License, Version 2.0 (the "License");
5695  * you may not use this file except in compliance with the License.
5696  * You may obtain a copy of the License at
5697  *
5698  *      http://www.apache.org/licenses/LICENSE-2.0
5699  *
5700  * Unless required by applicable law or agreed to in writing, software
5701  * distributed under the License is distributed on an "AS IS" BASIS,
5702  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5703  * See the License for the specific language governing permissions and
5704  * limitations under the License.
5705  */
5706 
5707 // gen_amalgamated expanded: #include "perfetto/ext/base/waitable_event.h"
5708 
5709 namespace perfetto {
5710 namespace base {
5711 
5712 WaitableEvent::WaitableEvent() = default;
5713 WaitableEvent::~WaitableEvent() = default;
5714 
Wait()5715 void WaitableEvent::Wait() {
5716   std::unique_lock<std::mutex> lock(mutex_);
5717   return event_.wait(lock, [this] { return notified_; });
5718 }
5719 
Notify()5720 void WaitableEvent::Notify() {
5721   std::unique_lock<std::mutex> lock(mutex_);
5722   notified_ = true;
5723   event_.notify_all();
5724 }
5725 
5726 }  // namespace base
5727 }  // namespace perfetto
5728 // gen_amalgamated begin source: src/base/watchdog_posix.cc
5729 // gen_amalgamated begin header: include/perfetto/ext/base/watchdog.h
5730 // gen_amalgamated begin header: include/perfetto/ext/base/watchdog_noop.h
5731 /*
5732  * Copyright (C) 2018 The Android Open Source Project
5733  *
5734  * Licensed under the Apache License, Version 2.0 (the "License");
5735  * you may not use this file except in compliance with the License.
5736  * You may obtain a copy of the License at
5737  *
5738  *      http://www.apache.org/licenses/LICENSE-2.0
5739  *
5740  * Unless required by applicable law or agreed to in writing, software
5741  * distributed under the License is distributed on an "AS IS" BASIS,
5742  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5743  * See the License for the specific language governing permissions and
5744  * limitations under the License.
5745  */
5746 
5747 #ifndef INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_NOOP_H_
5748 #define INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_NOOP_H_
5749 
5750 #include <stdint.h>
5751 
5752 namespace perfetto {
5753 namespace base {
5754 
5755 class Watchdog {
5756  public:
5757   class Timer {
5758    public:
5759     // Define an empty dtor to avoid "unused variable" errors on the call site.
Timer()5760     Timer() {}
Timer(const Timer &)5761     Timer(const Timer&) {}
~Timer()5762     ~Timer() {}
5763   };
GetInstance()5764   static Watchdog* GetInstance() {
5765     static Watchdog* watchdog = new Watchdog();
5766     return watchdog;
5767   }
CreateFatalTimer(uint32_t)5768   Timer CreateFatalTimer(uint32_t /*ms*/) { return Timer(); }
Start()5769   void Start() {}
SetMemoryLimit(uint64_t,uint32_t)5770   void SetMemoryLimit(uint64_t /*bytes*/, uint32_t /*window_ms*/) {}
SetCpuLimit(uint32_t,uint32_t)5771   void SetCpuLimit(uint32_t /*percentage*/, uint32_t /*window_ms*/) {}
5772 };
5773 
5774 }  // namespace base
5775 }  // namespace perfetto
5776 
5777 #endif  // INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_NOOP_H_
5778 /*
5779  * Copyright (C) 2018 The Android Open Source Project
5780  *
5781  * Licensed under the Apache License, Version 2.0 (the "License");
5782  * you may not use this file except in compliance with the License.
5783  * You may obtain a copy of the License at
5784  *
5785  *      http://www.apache.org/licenses/LICENSE-2.0
5786  *
5787  * Unless required by applicable law or agreed to in writing, software
5788  * distributed under the License is distributed on an "AS IS" BASIS,
5789  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5790  * See the License for the specific language governing permissions and
5791  * limitations under the License.
5792  */
5793 
5794 #ifndef INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_H_
5795 #define INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_H_
5796 
5797 #include <functional>
5798 
5799 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
5800 
5801 // The POSIX watchdog is only supported on Linux and Android in non-embedder
5802 // builds.
5803 #if PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
5804 // gen_amalgamated expanded: #include "perfetto/ext/base/watchdog_posix.h"
5805 #else
5806 // gen_amalgamated expanded: #include "perfetto/ext/base/watchdog_noop.h"
5807 #endif
5808 
5809 namespace perfetto {
5810 namespace base {
5811 
5812 // Make the limits more relaxed on desktop, where multi-GB traces are likely.
5813 // Multi-GB traces can take bursts of cpu time to write into disk at the end of
5814 // the trace.
5815 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
5816 constexpr uint32_t kWatchdogDefaultCpuLimit = 75;
5817 constexpr uint32_t kWatchdogDefaultCpuWindow = 5 * 60 * 1000;  // 5 minutes.
5818 #else
5819 constexpr uint32_t kWatchdogDefaultCpuLimit = 90;
5820 constexpr uint32_t kWatchdogDefaultCpuWindow = 10 * 60 * 1000;  // 10 minutes.
5821 #endif
5822 
5823 // The default memory margin we give to our processes. This is used as as a
5824 // constant to put on top of the trace buffers.
5825 constexpr uint64_t kWatchdogDefaultMemorySlack = 32 * 1024 * 1024;  // 32 MiB.
5826 constexpr uint32_t kWatchdogDefaultMemoryWindow = 30 * 1000;  // 30 seconds.
5827 
RunTaskWithWatchdogGuard(const std::function<void ()> & task)5828 inline void RunTaskWithWatchdogGuard(const std::function<void()>& task) {
5829   // Maximum time a single task can take in a TaskRunner before the
5830   // program suicides.
5831   constexpr int64_t kWatchdogMillis = 30000;  // 30s
5832 
5833   Watchdog::Timer handle =
5834       base::Watchdog::GetInstance()->CreateFatalTimer(kWatchdogMillis);
5835   task();
5836 
5837   // Suppress unused variable warnings in the client library amalgamated build.
5838   (void)kWatchdogDefaultCpuLimit;
5839   (void)kWatchdogDefaultCpuWindow;
5840   (void)kWatchdogDefaultMemorySlack;
5841   (void)kWatchdogDefaultMemoryWindow;
5842 }
5843 
5844 }  // namespace base
5845 }  // namespace perfetto
5846 
5847 #endif  // INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_H_
5848 /*
5849  * Copyright (C) 2018 The Android Open Source Project
5850  *
5851  * Licensed under the Apache License, Version 2.0 (the "License");
5852  * you may not use this file except in compliance with the License.
5853  * You may obtain a copy of the License at
5854  *
5855  *      http://www.apache.org/licenses/LICENSE-2.0
5856  *
5857  * Unless required by applicable law or agreed to in writing, software
5858  * distributed under the License is distributed on an "AS IS" BASIS,
5859  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5860  * See the License for the specific language governing permissions and
5861  * limitations under the License.
5862  */
5863 
5864 // gen_amalgamated expanded: #include "perfetto/ext/base/watchdog.h"
5865 
5866 #if PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
5867 
5868 #include <fcntl.h>
5869 #include <inttypes.h>
5870 #include <signal.h>
5871 #include <stdint.h>
5872 
5873 #include <fstream>
5874 #include <thread>
5875 
5876 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
5877 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
5878 // gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
5879 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
5880 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
5881 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
5882 
5883 namespace perfetto {
5884 namespace base {
5885 
5886 namespace {
5887 
5888 constexpr uint32_t kDefaultPollingInterval = 30 * 1000;
5889 
IsMultipleOf(uint32_t number,uint32_t divisor)5890 bool IsMultipleOf(uint32_t number, uint32_t divisor) {
5891   return number >= divisor && number % divisor == 0;
5892 }
5893 
MeanForArray(const uint64_t array[],size_t size)5894 double MeanForArray(const uint64_t array[], size_t size) {
5895   uint64_t total = 0;
5896   for (size_t i = 0; i < size; i++) {
5897     total += array[i];
5898   }
5899   return static_cast<double>(total / size);
5900 
5901 }
5902 
5903 }  //  namespace
5904 
ReadProcStat(int fd,ProcStat * out)5905 bool ReadProcStat(int fd, ProcStat* out) {
5906   char c[512];
5907   size_t c_pos = 0;
5908   while (c_pos < sizeof(c) - 1) {
5909     ssize_t rd = PERFETTO_EINTR(read(fd, c + c_pos, sizeof(c) - c_pos));
5910     if (rd < 0) {
5911       PERFETTO_ELOG("Failed to read stat file to enforce resource limits.");
5912       return false;
5913     }
5914     if (rd == 0)
5915       break;
5916     c_pos += static_cast<size_t>(rd);
5917   }
5918   PERFETTO_CHECK(c_pos < sizeof(c));
5919   c[c_pos] = '\0';
5920 
5921   if (sscanf(c,
5922              "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %lu "
5923              "%lu %*d %*d %*d %*d %*d %*d %*u %*u %ld",
5924              &out->utime, &out->stime, &out->rss_pages) != 3) {
5925     PERFETTO_ELOG("Invalid stat format: %s", c);
5926     return false;
5927   }
5928   return true;
5929 }
5930 
Watchdog(uint32_t polling_interval_ms)5931 Watchdog::Watchdog(uint32_t polling_interval_ms)
5932     : polling_interval_ms_(polling_interval_ms) {}
5933 
~Watchdog()5934 Watchdog::~Watchdog() {
5935   if (!thread_.joinable()) {
5936     PERFETTO_DCHECK(!enabled_);
5937     return;
5938   }
5939   PERFETTO_DCHECK(enabled_);
5940   enabled_ = false;
5941   exit_signal_.notify_one();
5942   thread_.join();
5943 }
5944 
GetInstance()5945 Watchdog* Watchdog::GetInstance() {
5946   static Watchdog* watchdog = new Watchdog(kDefaultPollingInterval);
5947   return watchdog;
5948 }
5949 
CreateFatalTimer(uint32_t ms)5950 Watchdog::Timer Watchdog::CreateFatalTimer(uint32_t ms) {
5951   if (!enabled_.load(std::memory_order_relaxed))
5952     return Watchdog::Timer(0);
5953 
5954   return Watchdog::Timer(ms);
5955 }
5956 
Start()5957 void Watchdog::Start() {
5958   std::lock_guard<std::mutex> guard(mutex_);
5959   if (thread_.joinable()) {
5960     PERFETTO_DCHECK(enabled_);
5961   } else {
5962     PERFETTO_DCHECK(!enabled_);
5963 
5964 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
5965     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
5966     // Kick the thread to start running but only on Android or Linux.
5967     enabled_ = true;
5968     thread_ = std::thread(&Watchdog::ThreadMain, this);
5969 #endif
5970   }
5971 }
5972 
SetMemoryLimit(uint64_t bytes,uint32_t window_ms)5973 void Watchdog::SetMemoryLimit(uint64_t bytes, uint32_t window_ms) {
5974   // Update the fields under the lock.
5975   std::lock_guard<std::mutex> guard(mutex_);
5976 
5977   PERFETTO_CHECK(IsMultipleOf(window_ms, polling_interval_ms_) || bytes == 0);
5978 
5979   size_t size = bytes == 0 ? 0 : window_ms / polling_interval_ms_ + 1;
5980   memory_window_bytes_.Reset(size);
5981   memory_limit_bytes_ = bytes;
5982 }
5983 
SetCpuLimit(uint32_t percentage,uint32_t window_ms)5984 void Watchdog::SetCpuLimit(uint32_t percentage, uint32_t window_ms) {
5985   std::lock_guard<std::mutex> guard(mutex_);
5986 
5987   PERFETTO_CHECK(percentage <= 100);
5988   PERFETTO_CHECK(IsMultipleOf(window_ms, polling_interval_ms_) ||
5989                  percentage == 0);
5990 
5991   size_t size = percentage == 0 ? 0 : window_ms / polling_interval_ms_ + 1;
5992   cpu_window_time_ticks_.Reset(size);
5993   cpu_limit_percentage_ = percentage;
5994 }
5995 
ThreadMain()5996 void Watchdog::ThreadMain() {
5997   base::ScopedFile stat_fd(base::OpenFile("/proc/self/stat", O_RDONLY));
5998   if (!stat_fd) {
5999     PERFETTO_ELOG("Failed to open stat file to enforce resource limits.");
6000     return;
6001   }
6002 
6003   std::unique_lock<std::mutex> guard(mutex_);
6004   for (;;) {
6005     exit_signal_.wait_for(guard,
6006                           std::chrono::milliseconds(polling_interval_ms_));
6007     if (!enabled_)
6008       return;
6009 
6010     lseek(stat_fd.get(), 0, SEEK_SET);
6011 
6012     ProcStat stat;
6013     if (!ReadProcStat(stat_fd.get(), &stat)) {
6014       return;
6015     }
6016 
6017     uint64_t cpu_time = stat.utime + stat.stime;
6018     uint64_t rss_bytes =
6019         static_cast<uint64_t>(stat.rss_pages) * base::GetSysPageSize();
6020 
6021     CheckMemory(rss_bytes);
6022     CheckCpu(cpu_time);
6023   }
6024 }
6025 
CheckMemory(uint64_t rss_bytes)6026 void Watchdog::CheckMemory(uint64_t rss_bytes) {
6027   if (memory_limit_bytes_ == 0)
6028     return;
6029 
6030   // Add the current stat value to the ring buffer and check that the mean
6031   // remains under our threshold.
6032   if (memory_window_bytes_.Push(rss_bytes)) {
6033     if (memory_window_bytes_.Mean() > static_cast<double>(memory_limit_bytes_)) {
6034       PERFETTO_ELOG(
6035           "Memory watchdog trigger. Memory window of %f bytes is above the "
6036           "%" PRIu64 " bytes limit.",
6037           memory_window_bytes_.Mean(), memory_limit_bytes_);
6038       kill(getpid(), SIGABRT);
6039     }
6040   }
6041 }
6042 
CheckCpu(uint64_t cpu_time)6043 void Watchdog::CheckCpu(uint64_t cpu_time) {
6044   if (cpu_limit_percentage_ == 0)
6045     return;
6046 
6047   // Add the cpu time to the ring buffer.
6048   if (cpu_window_time_ticks_.Push(cpu_time)) {
6049     // Compute the percentage over the whole window and check that it remains
6050     // under the threshold.
6051     uint64_t difference_ticks = cpu_window_time_ticks_.NewestWhenFull() -
6052                                 cpu_window_time_ticks_.OldestWhenFull();
6053     double window_interval_ticks =
6054         (static_cast<double>(WindowTimeForRingBuffer(cpu_window_time_ticks_)) /
6055          1000.0) *
6056         static_cast<double>(sysconf(_SC_CLK_TCK));
6057     double percentage = static_cast<double>(difference_ticks) /
6058                         static_cast<double>(window_interval_ticks) * 100;
6059     if (percentage > cpu_limit_percentage_) {
6060       PERFETTO_ELOG("CPU watchdog trigger. %f%% CPU use is above the %" PRIu32
6061                     "%% CPU limit.",
6062                     percentage, cpu_limit_percentage_);
6063       kill(getpid(), SIGABRT);
6064     }
6065   }
6066 }
6067 
WindowTimeForRingBuffer(const WindowedInterval & window)6068 uint32_t Watchdog::WindowTimeForRingBuffer(const WindowedInterval& window) {
6069   return static_cast<uint32_t>(window.size() - 1) * polling_interval_ms_;
6070 }
6071 
Push(uint64_t sample)6072 bool Watchdog::WindowedInterval::Push(uint64_t sample) {
6073   // Add the sample to the current position in the ring buffer.
6074   buffer_[position_] = sample;
6075 
6076   // Update the position with next one circularily.
6077   position_ = (position_ + 1) % size_;
6078 
6079   // Set the filled flag the first time we wrap.
6080   filled_ = filled_ || position_ == 0;
6081   return filled_;
6082 }
6083 
Mean() const6084 double Watchdog::WindowedInterval::Mean() const {
6085   return MeanForArray(buffer_.get(), size_);
6086 }
6087 
Clear()6088 void Watchdog::WindowedInterval::Clear() {
6089   position_ = 0;
6090   buffer_.reset(new uint64_t[size_]());
6091 }
6092 
Reset(size_t new_size)6093 void Watchdog::WindowedInterval::Reset(size_t new_size) {
6094   position_ = 0;
6095   size_ = new_size;
6096   buffer_.reset(new_size == 0 ? nullptr : new uint64_t[new_size]());
6097 }
6098 
Timer(uint32_t ms)6099 Watchdog::Timer::Timer(uint32_t ms) {
6100   if (!ms)
6101     return;  // No-op timer created when the watchdog is disabled.
6102 
6103   struct sigevent sev = {};
6104   timer_t timerid;
6105   sev.sigev_notify = SIGEV_THREAD_ID;
6106   sev._sigev_un._tid = base::GetThreadId();
6107   sev.sigev_signo = SIGABRT;
6108   PERFETTO_CHECK(timer_create(CLOCK_MONOTONIC, &sev, &timerid) != -1);
6109   timerid_ = base::make_optional(timerid);
6110   struct itimerspec its = {};
6111   its.it_value.tv_sec = ms / 1000;
6112   its.it_value.tv_nsec = 1000000L * (ms % 1000);
6113   PERFETTO_CHECK(timer_settime(timerid_.value(), 0, &its, nullptr) != -1);
6114 }
6115 
~Timer()6116 Watchdog::Timer::~Timer() {
6117   if (timerid_) {
6118     timer_delete(timerid_.value());
6119   }
6120 }
6121 
Timer(Timer && other)6122 Watchdog::Timer::Timer(Timer&& other) noexcept {
6123   timerid_ = std::move(other.timerid_);
6124   other.timerid_ = base::nullopt;
6125 }
6126 
6127 }  // namespace base
6128 }  // namespace perfetto
6129 
6130 #endif  // PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
6131 // gen_amalgamated begin source: src/base/thread_task_runner.cc
6132 // gen_amalgamated begin header: include/perfetto/ext/base/thread_task_runner.h
6133 // gen_amalgamated begin header: include/perfetto/ext/base/unix_task_runner.h
6134 /*
6135  * Copyright (C) 2017 The Android Open Source Project
6136  *
6137  * Licensed under the Apache License, Version 2.0 (the "License");
6138  * you may not use this file except in compliance with the License.
6139  * You may obtain a copy of the License at
6140  *
6141  *      http://www.apache.org/licenses/LICENSE-2.0
6142  *
6143  * Unless required by applicable law or agreed to in writing, software
6144  * distributed under the License is distributed on an "AS IS" BASIS,
6145  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6146  * See the License for the specific language governing permissions and
6147  * limitations under the License.
6148  */
6149 
6150 #ifndef INCLUDE_PERFETTO_EXT_BASE_UNIX_TASK_RUNNER_H_
6151 #define INCLUDE_PERFETTO_EXT_BASE_UNIX_TASK_RUNNER_H_
6152 
6153 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
6154 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
6155 // gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
6156 // gen_amalgamated expanded: #include "perfetto/base/time.h"
6157 // gen_amalgamated expanded: #include "perfetto/ext/base/event_fd.h"
6158 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
6159 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
6160 
6161 #include <chrono>
6162 #include <deque>
6163 #include <map>
6164 #include <mutex>
6165 #include <vector>
6166 
6167 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6168 #include <poll.h>
6169 #endif
6170 
6171 namespace perfetto {
6172 namespace base {
6173 
6174 // Runs a task runner on the current thread.
6175 //
6176 // Implementation note: we currently assume (and enforce in debug builds) that
6177 // Run() is called from the thread that constructed the UnixTaskRunner. This is
6178 // not strictly necessary, and we could instead track the thread that invokes
6179 // Run(). However, a related property that *might* be important to enforce is
6180 // that the destructor runs on the task-running thread. Otherwise, if there are
6181 // still-pending tasks at the time of destruction, we would destroy those
6182 // outside of the task thread (which might be unexpected to the caller). On the
6183 // other hand, the std::function task interface discourages use of any
6184 // resource-owning tasks (as the callable needs to be copyable), so this might
6185 // not be important in practice.
6186 //
6187 // TODO(rsavitski): consider adding a thread-check in the destructor, after
6188 // auditing existing usages.
6189 // TODO(primiano): rename this to TaskRunnerImpl. The "Unix" part is misleading
6190 // now as it supports also Windows.
6191 class UnixTaskRunner : public TaskRunner {
6192  public:
6193   UnixTaskRunner();
6194   ~UnixTaskRunner() override;
6195 
6196   // Start executing tasks. Doesn't return until Quit() is called. Run() may be
6197   // called multiple times on the same task runner.
6198   void Run();
6199   void Quit();
6200 
6201   // Checks whether there are any pending immediate tasks to run. Note that
6202   // delayed tasks don't count even if they are due to run.
6203   bool IsIdleForTesting();
6204 
6205   // TaskRunner implementation:
6206   void PostTask(std::function<void()>) override;
6207   void PostDelayedTask(std::function<void()>, uint32_t delay_ms) override;
6208   void AddFileDescriptorWatch(PlatformHandle, std::function<void()>) override;
6209   void RemoveFileDescriptorWatch(PlatformHandle) override;
6210   bool RunsTasksOnCurrentThread() const override;
6211 
6212   // Returns true if the task runner is quitting, or has quit and hasn't been
6213   // restarted since. Exposed primarily for ThreadTaskRunner, not necessary for
6214   // normal use of this class.
6215   bool QuitCalled();
6216 
6217  private:
6218   void WakeUp();
6219   void UpdateWatchTasksLocked();
6220   int GetDelayMsToNextTaskLocked() const;
6221   void RunImmediateAndDelayedTask();
6222   void PostFileDescriptorWatches(uint64_t windows_wait_result);
6223   void RunFileDescriptorWatch(PlatformHandle);
6224 
6225   ThreadChecker thread_checker_;
6226   PlatformThreadId created_thread_id_ = GetThreadId();
6227 
6228   EventFd event_;
6229 
6230 // The array of fds/handles passed to poll(2) / WaitForMultipleObjects().
6231 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6232   std::vector<PlatformHandle> poll_fds_;
6233 #else
6234   std::vector<struct pollfd> poll_fds_;
6235 #endif
6236 
6237   // --- Begin lock-protected members ---
6238 
6239   std::mutex lock_;
6240 
6241   std::deque<std::function<void()>> immediate_tasks_;
6242   std::multimap<TimeMillis, std::function<void()>> delayed_tasks_;
6243   bool quit_ = false;
6244 
6245   struct WatchTask {
6246     std::function<void()> callback;
6247 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6248     // On UNIX systems we make the FD number negative in |poll_fds_| to avoid
6249     // polling it again until the queued task runs. On Windows we can't do that.
6250     // Instead we keep track of its state here.
6251     bool pending = false;
6252 #else
6253     size_t poll_fd_index;  // Index into |poll_fds_|.
6254 #endif
6255   };
6256 
6257   std::map<PlatformHandle, WatchTask> watch_tasks_;
6258   bool watch_tasks_changed_ = false;
6259 
6260   // --- End lock-protected members ---
6261 };
6262 
6263 }  // namespace base
6264 }  // namespace perfetto
6265 
6266 #endif  // INCLUDE_PERFETTO_EXT_BASE_UNIX_TASK_RUNNER_H_
6267 /*
6268  * Copyright (C) 2019 The Android Open Source Project
6269  *
6270  * Licensed under the Apache License, Version 2.0 (the "License");
6271  * you may not use this file except in compliance with the License.
6272  * You may obtain a copy of the License at
6273  *
6274  *      http://www.apache.org/licenses/LICENSE-2.0
6275  *
6276  * Unless required by applicable law or agreed to in writing, software
6277  * distributed under the License is distributed on an "AS IS" BASIS,
6278  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6279  * See the License for the specific language governing permissions and
6280  * limitations under the License.
6281  */
6282 
6283 #ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_TASK_RUNNER_H_
6284 #define INCLUDE_PERFETTO_EXT_BASE_THREAD_TASK_RUNNER_H_
6285 
6286 #include <functional>
6287 #include <thread>
6288 
6289 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_task_runner.h"
6290 
6291 namespace perfetto {
6292 namespace base {
6293 
6294 // A UnixTaskRunner backed by a dedicated task thread. Shuts down the runner and
6295 // joins the thread upon destruction. Can be moved to transfer ownership.
6296 //
6297 // Guarantees that:
6298 // * the UnixTaskRunner will be constructed and destructed on the task thread.
6299 // * the task thread will live for the lifetime of the UnixTaskRunner.
6300 //
6301 class PERFETTO_EXPORT ThreadTaskRunner : public TaskRunner {
6302  public:
CreateAndStart(const std::string & name="")6303   static ThreadTaskRunner CreateAndStart(const std::string& name = "") {
6304     return ThreadTaskRunner(name);
6305   }
6306 
6307   ThreadTaskRunner(const ThreadTaskRunner&) = delete;
6308   ThreadTaskRunner& operator=(const ThreadTaskRunner&) = delete;
6309 
6310   ThreadTaskRunner(ThreadTaskRunner&&) noexcept;
6311   ThreadTaskRunner& operator=(ThreadTaskRunner&&);
6312   ~ThreadTaskRunner() override;
6313 
6314   // Executes the given function on the task runner thread and blocks the caller
6315   // thread until the function has run.
6316   void PostTaskAndWaitForTesting(std::function<void()>);
6317 
6318   // Can be called from another thread to get the CPU time of the thread the
6319   // task-runner is executing on.
6320   uint64_t GetThreadCPUTimeNsForTesting();
6321 
6322   // Returns a pointer to the UnixTaskRunner, which is valid for the lifetime of
6323   // this ThreadTaskRunner object (unless this object is moved-from, in which
6324   // case the pointer remains valid for the lifetime of the new owning
6325   // ThreadTaskRunner).
6326   //
6327   // Warning: do not call Quit() on the returned runner pointer, the termination
6328   // should be handled exclusively by this class' destructor.
get() const6329   UnixTaskRunner* get() const { return task_runner_; }
6330 
6331   // TaskRunner implementation.
6332   // These methods just proxy to the underlying task_runner_.
6333   void PostTask(std::function<void()>) override;
6334   void PostDelayedTask(std::function<void()>, uint32_t delay_ms) override;
6335   void AddFileDescriptorWatch(PlatformHandle, std::function<void()>) override;
6336   void RemoveFileDescriptorWatch(PlatformHandle) override;
6337   bool RunsTasksOnCurrentThread() const override;
6338 
6339  private:
6340   explicit ThreadTaskRunner(const std::string& name);
6341   void RunTaskThread(std::function<void(UnixTaskRunner*)> initializer);
6342 
6343   std::thread thread_;
6344   std::string name_;
6345   UnixTaskRunner* task_runner_ = nullptr;
6346 };
6347 
6348 }  // namespace base
6349 }  // namespace perfetto
6350 
6351 #endif  // INCLUDE_PERFETTO_EXT_BASE_THREAD_TASK_RUNNER_H_
6352 // gen_amalgamated begin header: include/perfetto/ext/base/thread_utils.h
6353 /*
6354  * Copyright (C) 2020 The Android Open Source Project
6355  *
6356  * Licensed under the Apache License, Version 2.0 (the "License");
6357  * you may not use this file except in compliance with the License.
6358  * You may obtain a copy of the License at
6359  *
6360  *      http://www.apache.org/licenses/LICENSE-2.0
6361  *
6362  * Unless required by applicable law or agreed to in writing, software
6363  * distributed under the License is distributed on an "AS IS" BASIS,
6364  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6365  * See the License for the specific language governing permissions and
6366  * limitations under the License.
6367  */
6368 
6369 #ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_UTILS_H_
6370 #define INCLUDE_PERFETTO_EXT_BASE_THREAD_UTILS_H_
6371 
6372 #include <string>
6373 
6374 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
6375 
6376 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
6377     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
6378     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
6379 #include <pthread.h>
6380 #include <string.h>
6381 #include <algorithm>
6382 #endif
6383 
6384 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
6385 #include <sys/prctl.h>
6386 #endif
6387 
6388 // Internal implementation utils that aren't as widely useful/supported as
6389 // base/thread_utils.h.
6390 
6391 namespace perfetto {
6392 namespace base {
6393 
6394 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
6395     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
6396     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
6397 // Sets the "comm" of the calling thread to the first 15 chars of the given
6398 // string.
MaybeSetThreadName(const std::string & name)6399 inline bool MaybeSetThreadName(const std::string& name) {
6400   char buf[16] = {};
6401   size_t sz = std::min(name.size(), static_cast<size_t>(15));
6402   strncpy(buf, name.c_str(), sz);
6403 
6404 #if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
6405   return pthread_setname_np(buf) == 0;
6406 #else
6407   return pthread_setname_np(pthread_self(), buf) == 0;
6408 #endif
6409 }
6410 
GetThreadName(std::string & out_result)6411 inline bool GetThreadName(std::string& out_result) {
6412   char buf[16] = {};
6413 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
6414   if (prctl(PR_GET_NAME, buf) != 0)
6415     return false;
6416 #else
6417   if (pthread_getname_np(pthread_self(), buf, sizeof(buf)) != 0)
6418     return false;
6419 #endif
6420   out_result = std::string(buf);
6421   return true;
6422 }
6423 
6424 #else
6425 inline bool MaybeSetThreadName(const std::string&) {
6426   return false;
6427 }
6428 inline bool GetThreadName(std::string&) {
6429   return false;
6430 }
6431 #endif
6432 
6433 }  // namespace base
6434 }  // namespace perfetto
6435 
6436 #endif  // INCLUDE_PERFETTO_EXT_BASE_THREAD_UTILS_H_
6437 /*
6438  * Copyright (C) 2019 The Android Open Source Project
6439  *
6440  * Licensed under the Apache License, Version 2.0 (the "License");
6441  * you may not use this file except in compliance with the License.
6442  * You may obtain a copy of the License at
6443  *
6444  *      http://www.apache.org/licenses/LICENSE-2.0
6445  *
6446  * Unless required by applicable law or agreed to in writing, software
6447  * distributed under the License is distributed on an "AS IS" BASIS,
6448  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6449  * See the License for the specific language governing permissions and
6450  * limitations under the License.
6451  */
6452 
6453 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
6454 
6455 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_task_runner.h"
6456 
6457 #include <condition_variable>
6458 #include <functional>
6459 #include <mutex>
6460 #include <thread>
6461 
6462 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
6463 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_utils.h"
6464 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_task_runner.h"
6465 
6466 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
6467     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
6468 #include <sys/prctl.h>
6469 #endif
6470 
6471 namespace perfetto {
6472 namespace base {
6473 
ThreadTaskRunner(ThreadTaskRunner && other)6474 ThreadTaskRunner::ThreadTaskRunner(ThreadTaskRunner&& other) noexcept
6475     : thread_(std::move(other.thread_)), task_runner_(other.task_runner_) {
6476   other.task_runner_ = nullptr;
6477 }
6478 
operator =(ThreadTaskRunner && other)6479 ThreadTaskRunner& ThreadTaskRunner::operator=(ThreadTaskRunner&& other) {
6480   this->~ThreadTaskRunner();
6481   new (this) ThreadTaskRunner(std::move(other));
6482   return *this;
6483 }
6484 
~ThreadTaskRunner()6485 ThreadTaskRunner::~ThreadTaskRunner() {
6486   if (task_runner_) {
6487     PERFETTO_CHECK(!task_runner_->QuitCalled());
6488     task_runner_->Quit();
6489 
6490     PERFETTO_DCHECK(thread_.joinable());
6491   }
6492   if (thread_.joinable())
6493     thread_.join();
6494 }
6495 
ThreadTaskRunner(const std::string & name)6496 ThreadTaskRunner::ThreadTaskRunner(const std::string& name) : name_(name) {
6497   std::mutex init_lock;
6498   std::condition_variable init_cv;
6499 
6500   std::function<void(UnixTaskRunner*)> initializer =
6501       [this, &init_lock, &init_cv](UnixTaskRunner* task_runner) {
6502         std::lock_guard<std::mutex> lock(init_lock);
6503         task_runner_ = task_runner;
6504         // Notify while still holding the lock, as init_cv ceases to exist as
6505         // soon as the main thread observes a non-null task_runner_, and it can
6506         // wake up spuriously (i.e. before the notify if we had unlocked before
6507         // notifying).
6508         init_cv.notify_one();
6509       };
6510 
6511   thread_ = std::thread(&ThreadTaskRunner::RunTaskThread, this,
6512                         std::move(initializer));
6513 
6514   std::unique_lock<std::mutex> lock(init_lock);
6515   init_cv.wait(lock, [this] { return !!task_runner_; });
6516 }
6517 
RunTaskThread(std::function<void (UnixTaskRunner *)> initializer)6518 void ThreadTaskRunner::RunTaskThread(
6519     std::function<void(UnixTaskRunner*)> initializer) {
6520   if (!name_.empty()) {
6521     base::MaybeSetThreadName(name_);
6522   }
6523 
6524   UnixTaskRunner task_runner;
6525   task_runner.PostTask(std::bind(std::move(initializer), &task_runner));
6526   task_runner.Run();
6527 }
6528 
PostTaskAndWaitForTesting(std::function<void ()> fn)6529 void ThreadTaskRunner::PostTaskAndWaitForTesting(std::function<void()> fn) {
6530   std::mutex mutex;
6531   std::condition_variable cv;
6532 
6533   std::unique_lock<std::mutex> lock(mutex);
6534   bool done = false;
6535   task_runner_->PostTask([&mutex, &cv, &done, &fn] {
6536     fn();
6537 
6538     std::lock_guard<std::mutex> inner_lock(mutex);
6539     done = true;
6540     cv.notify_one();
6541   });
6542   cv.wait(lock, [&done] { return done; });
6543 }
6544 
GetThreadCPUTimeNsForTesting()6545 uint64_t ThreadTaskRunner::GetThreadCPUTimeNsForTesting() {
6546   uint64_t thread_time_ns = 0;
6547   PostTaskAndWaitForTesting([&thread_time_ns] {
6548     thread_time_ns = static_cast<uint64_t>(base::GetThreadCPUTimeNs().count());
6549   });
6550   return thread_time_ns;
6551 }
6552 
PostTask(std::function<void ()> task)6553 void ThreadTaskRunner::PostTask(std::function<void()> task) {
6554   task_runner_->PostTask(std::move(task));
6555 }
6556 
PostDelayedTask(std::function<void ()> task,uint32_t delay_ms)6557 void ThreadTaskRunner::PostDelayedTask(std::function<void()> task,
6558                                        uint32_t delay_ms) {
6559   task_runner_->PostDelayedTask(std::move(task), delay_ms);
6560 }
6561 
AddFileDescriptorWatch(PlatformHandle handle,std::function<void ()> watch_task)6562 void ThreadTaskRunner::AddFileDescriptorWatch(
6563     PlatformHandle handle,
6564     std::function<void()> watch_task) {
6565   task_runner_->AddFileDescriptorWatch(handle, std::move(watch_task));
6566 }
6567 
RemoveFileDescriptorWatch(PlatformHandle handle)6568 void ThreadTaskRunner::RemoveFileDescriptorWatch(PlatformHandle handle) {
6569   task_runner_->RemoveFileDescriptorWatch(handle);
6570 }
6571 
RunsTasksOnCurrentThread() const6572 bool ThreadTaskRunner::RunsTasksOnCurrentThread() const {
6573   return task_runner_->RunsTasksOnCurrentThread();
6574 }
6575 
6576 }  // namespace base
6577 }  // namespace perfetto
6578 // gen_amalgamated begin source: src/base/unix_task_runner.cc
6579 /*
6580  * Copyright (C) 2017 The Android Open Source Project
6581  *
6582  * Licensed under the Apache License, Version 2.0 (the "License");
6583  * you may not use this file except in compliance with the License.
6584  * You may obtain a copy of the License at
6585  *
6586  *      http://www.apache.org/licenses/LICENSE-2.0
6587  *
6588  * Unless required by applicable law or agreed to in writing, software
6589  * distributed under the License is distributed on an "AS IS" BASIS,
6590  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6591  * See the License for the specific language governing permissions and
6592  * limitations under the License.
6593  */
6594 
6595 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
6596 
6597 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_task_runner.h"
6598 
6599 #include <errno.h>
6600 #include <stdlib.h>
6601 
6602 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6603 #include <Windows.h>
6604 #include <synchapi.h>
6605 #else
6606 #include <unistd.h>
6607 #endif
6608 
6609 #include <algorithm>
6610 #include <limits>
6611 
6612 // gen_amalgamated expanded: #include "perfetto/ext/base/watchdog.h"
6613 
6614 namespace perfetto {
6615 namespace base {
6616 
UnixTaskRunner()6617 UnixTaskRunner::UnixTaskRunner() {
6618   AddFileDescriptorWatch(event_.fd(), [] {
6619     // Not reached -- see PostFileDescriptorWatches().
6620     PERFETTO_DFATAL("Should be unreachable.");
6621   });
6622 }
6623 
6624 UnixTaskRunner::~UnixTaskRunner() = default;
6625 
WakeUp()6626 void UnixTaskRunner::WakeUp() {
6627   event_.Notify();
6628 }
6629 
Run()6630 void UnixTaskRunner::Run() {
6631   PERFETTO_DCHECK_THREAD(thread_checker_);
6632   created_thread_id_ = GetThreadId();
6633   quit_ = false;
6634   for (;;) {
6635     int poll_timeout_ms;
6636     {
6637       std::lock_guard<std::mutex> lock(lock_);
6638       if (quit_)
6639         return;
6640       poll_timeout_ms = GetDelayMsToNextTaskLocked();
6641       UpdateWatchTasksLocked();
6642     }
6643 
6644 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6645     DWORD timeout =
6646         poll_timeout_ms >= 0 ? static_cast<DWORD>(poll_timeout_ms) : INFINITE;
6647     DWORD ret =
6648         WaitForMultipleObjects(static_cast<DWORD>(poll_fds_.size()),
6649                                &poll_fds_[0], /*bWaitAll=*/false, timeout);
6650     // Unlike poll(2), WaitForMultipleObjects() returns only *one* handle in the
6651     // set, even when >1 is signalled. In order to avoid starvation,
6652     // PostFileDescriptorWatches() will WaitForSingleObject() each other handle
6653     // to ensure fairness. |ret| here is passed just to avoid an extra
6654     // WaitForSingleObject() for the one handle that WaitForMultipleObject()
6655     // returned.
6656     PostFileDescriptorWatches(ret);
6657 #else
6658     int ret = PERFETTO_EINTR(poll(
6659         &poll_fds_[0], static_cast<nfds_t>(poll_fds_.size()), poll_timeout_ms));
6660     PERFETTO_CHECK(ret >= 0);
6661     PostFileDescriptorWatches(0 /*ignored*/);
6662 #endif
6663 
6664     // To avoid starvation we always interleave all types of tasks -- immediate,
6665     // delayed and file descriptor watches.
6666     RunImmediateAndDelayedTask();
6667   }
6668 }
6669 
Quit()6670 void UnixTaskRunner::Quit() {
6671   std::lock_guard<std::mutex> lock(lock_);
6672   quit_ = true;
6673   WakeUp();
6674 }
6675 
QuitCalled()6676 bool UnixTaskRunner::QuitCalled() {
6677   std::lock_guard<std::mutex> lock(lock_);
6678   return quit_;
6679 }
6680 
IsIdleForTesting()6681 bool UnixTaskRunner::IsIdleForTesting() {
6682   std::lock_guard<std::mutex> lock(lock_);
6683   return immediate_tasks_.empty();
6684 }
6685 
UpdateWatchTasksLocked()6686 void UnixTaskRunner::UpdateWatchTasksLocked() {
6687   PERFETTO_DCHECK_THREAD(thread_checker_);
6688 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6689   if (!watch_tasks_changed_)
6690     return;
6691   watch_tasks_changed_ = false;
6692 #endif
6693   poll_fds_.clear();
6694   for (auto& it : watch_tasks_) {
6695     PlatformHandle handle = it.first;
6696     WatchTask& watch_task = it.second;
6697 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6698     if (!watch_task.pending)
6699       poll_fds_.push_back(handle);
6700 #else
6701     watch_task.poll_fd_index = poll_fds_.size();
6702     poll_fds_.push_back({handle, POLLIN | POLLHUP, 0});
6703 #endif
6704   }
6705 }
6706 
RunImmediateAndDelayedTask()6707 void UnixTaskRunner::RunImmediateAndDelayedTask() {
6708   // If locking overhead becomes an issue, add a separate work queue.
6709   std::function<void()> immediate_task;
6710   std::function<void()> delayed_task;
6711   TimeMillis now = GetWallTimeMs();
6712   {
6713     std::lock_guard<std::mutex> lock(lock_);
6714     if (!immediate_tasks_.empty()) {
6715       immediate_task = std::move(immediate_tasks_.front());
6716       immediate_tasks_.pop_front();
6717     }
6718     if (!delayed_tasks_.empty()) {
6719       auto it = delayed_tasks_.begin();
6720       if (now >= it->first) {
6721         delayed_task = std::move(it->second);
6722         delayed_tasks_.erase(it);
6723       }
6724     }
6725   }
6726 
6727   errno = 0;
6728   if (immediate_task)
6729     RunTaskWithWatchdogGuard(immediate_task);
6730   errno = 0;
6731   if (delayed_task)
6732     RunTaskWithWatchdogGuard(delayed_task);
6733 }
6734 
PostFileDescriptorWatches(uint64_t windows_wait_result)6735 void UnixTaskRunner::PostFileDescriptorWatches(uint64_t windows_wait_result) {
6736   PERFETTO_DCHECK_THREAD(thread_checker_);
6737   for (size_t i = 0; i < poll_fds_.size(); i++) {
6738 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6739     const PlatformHandle handle = poll_fds_[i];
6740     // |windows_wait_result| is the result of WaitForMultipleObjects() call. If
6741     // one of the objects was signalled, it will have a value between
6742     // [0, poll_fds_.size()].
6743     if (i != windows_wait_result &&
6744         WaitForSingleObject(handle, 0) != WAIT_OBJECT_0) {
6745       continue;
6746     }
6747 #else
6748     base::ignore_result(windows_wait_result);
6749     const PlatformHandle handle = poll_fds_[i].fd;
6750     if (!(poll_fds_[i].revents & (POLLIN | POLLHUP)))
6751       continue;
6752     poll_fds_[i].revents = 0;
6753 #endif
6754 
6755     // The wake-up event is handled inline to avoid an infinite recursion of
6756     // posted tasks.
6757     if (handle == event_.fd()) {
6758       event_.Clear();
6759       continue;
6760     }
6761 
6762     // Binding to |this| is safe since we are the only object executing the
6763     // task.
6764     PostTask(std::bind(&UnixTaskRunner::RunFileDescriptorWatch, this, handle));
6765 
6766     // Flag the task as pending.
6767 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6768     // On Windows this is done by marking the WatchTask entry as pending. This
6769     // is more expensive than Linux as requires rebuilding the |poll_fds_|
6770     // vector on each call. There doesn't seem to be a good alternative though.
6771     auto it = watch_tasks_.find(handle);
6772     PERFETTO_CHECK(it != watch_tasks_.end());
6773     PERFETTO_DCHECK(!it->second.pending);
6774     it->second.pending = true;
6775 #else
6776     // On UNIX systems instead, we just make the fd negative while its task is
6777     // pending. This makes poll(2) ignore the fd.
6778     PERFETTO_DCHECK(poll_fds_[i].fd >= 0);
6779     poll_fds_[i].fd = -poll_fds_[i].fd;
6780 #endif
6781   }
6782 }
6783 
RunFileDescriptorWatch(PlatformHandle fd)6784 void UnixTaskRunner::RunFileDescriptorWatch(PlatformHandle fd) {
6785   std::function<void()> task;
6786   {
6787     std::lock_guard<std::mutex> lock(lock_);
6788     auto it = watch_tasks_.find(fd);
6789     if (it == watch_tasks_.end())
6790       return;
6791     WatchTask& watch_task = it->second;
6792 
6793     // Make poll(2) pay attention to the fd again. Since another thread may have
6794     // updated this watch we need to refresh the set first.
6795     UpdateWatchTasksLocked();
6796 
6797 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6798     // On Windows we manually track the presence of outstanding tasks for the
6799     // watch. The UpdateWatchTasksLocked() in the Run() loop will re-add the
6800     // task to the |poll_fds_| vector.
6801     PERFETTO_DCHECK(watch_task.pending);
6802     watch_task.pending = false;
6803 #else
6804     size_t fd_index = watch_task.poll_fd_index;
6805     PERFETTO_DCHECK(fd_index < poll_fds_.size());
6806     PERFETTO_DCHECK(::abs(poll_fds_[fd_index].fd) == fd);
6807     poll_fds_[fd_index].fd = fd;
6808 #endif
6809     task = watch_task.callback;
6810   }
6811   errno = 0;
6812   RunTaskWithWatchdogGuard(task);
6813 }
6814 
GetDelayMsToNextTaskLocked() const6815 int UnixTaskRunner::GetDelayMsToNextTaskLocked() const {
6816   PERFETTO_DCHECK_THREAD(thread_checker_);
6817   if (!immediate_tasks_.empty())
6818     return 0;
6819   if (!delayed_tasks_.empty()) {
6820     TimeMillis diff = delayed_tasks_.begin()->first - GetWallTimeMs();
6821     return std::max(0, static_cast<int>(diff.count()));
6822   }
6823   return -1;
6824 }
6825 
PostTask(std::function<void ()> task)6826 void UnixTaskRunner::PostTask(std::function<void()> task) {
6827   bool was_empty;
6828   {
6829     std::lock_guard<std::mutex> lock(lock_);
6830     was_empty = immediate_tasks_.empty();
6831     immediate_tasks_.push_back(std::move(task));
6832   }
6833   if (was_empty)
6834     WakeUp();
6835 }
6836 
PostDelayedTask(std::function<void ()> task,uint32_t delay_ms)6837 void UnixTaskRunner::PostDelayedTask(std::function<void()> task,
6838                                      uint32_t delay_ms) {
6839   TimeMillis runtime = GetWallTimeMs() + TimeMillis(delay_ms);
6840   {
6841     std::lock_guard<std::mutex> lock(lock_);
6842     delayed_tasks_.insert(std::make_pair(runtime, std::move(task)));
6843   }
6844   WakeUp();
6845 }
6846 
AddFileDescriptorWatch(PlatformHandle fd,std::function<void ()> task)6847 void UnixTaskRunner::AddFileDescriptorWatch(PlatformHandle fd,
6848                                             std::function<void()> task) {
6849   PERFETTO_DCHECK(PlatformHandleChecker::IsValid(fd));
6850   {
6851     std::lock_guard<std::mutex> lock(lock_);
6852     PERFETTO_DCHECK(!watch_tasks_.count(fd));
6853     WatchTask& watch_task = watch_tasks_[fd];
6854     watch_task.callback = std::move(task);
6855 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6856     watch_task.pending = false;
6857 #else
6858     watch_task.poll_fd_index = SIZE_MAX;
6859 #endif
6860     watch_tasks_changed_ = true;
6861   }
6862   WakeUp();
6863 }
6864 
RemoveFileDescriptorWatch(PlatformHandle fd)6865 void UnixTaskRunner::RemoveFileDescriptorWatch(PlatformHandle fd) {
6866   PERFETTO_DCHECK(PlatformHandleChecker::IsValid(fd));
6867   {
6868     std::lock_guard<std::mutex> lock(lock_);
6869     PERFETTO_DCHECK(watch_tasks_.count(fd));
6870     watch_tasks_.erase(fd);
6871     watch_tasks_changed_ = true;
6872   }
6873   // No need to schedule a wake-up for this.
6874 }
6875 
RunsTasksOnCurrentThread() const6876 bool UnixTaskRunner::RunsTasksOnCurrentThread() const {
6877   return GetThreadId() == created_thread_id_;
6878 }
6879 
6880 }  // namespace base
6881 }  // namespace perfetto
6882 // gen_amalgamated begin source: src/base/subprocess.cc
6883 // gen_amalgamated begin header: include/perfetto/ext/base/subprocess.h
6884 /*
6885  * Copyright (C) 2020 The Android Open Source Project
6886  *
6887  * Licensed under the Apache License, Version 2.0 (the "License");
6888  * you may not use this file except in compliance with the License.
6889  * You may obtain a copy of the License at
6890  *
6891  *      http://www.apache.org/licenses/LICENSE-2.0
6892  *
6893  * Unless required by applicable law or agreed to in writing, software
6894  * distributed under the License is distributed on an "AS IS" BASIS,
6895  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6896  * See the License for the specific language governing permissions and
6897  * limitations under the License.
6898  */
6899 
6900 #ifndef INCLUDE_PERFETTO_EXT_BASE_SUBPROCESS_H_
6901 #define INCLUDE_PERFETTO_EXT_BASE_SUBPROCESS_H_
6902 
6903 #include <condition_variable>
6904 #include <functional>
6905 #include <initializer_list>
6906 #include <mutex>
6907 #include <string>
6908 #include <thread>
6909 #include <vector>
6910 
6911 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
6912 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
6913 // gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
6914 // gen_amalgamated expanded: #include "perfetto/base/proc_utils.h"
6915 // gen_amalgamated expanded: #include "perfetto/ext/base/event_fd.h"
6916 // gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
6917 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
6918 
6919 namespace perfetto {
6920 namespace base {
6921 
6922 // Handles creation and lifecycle management of subprocesses, taking care of
6923 // all subtleties involved in handling processes on UNIX.
6924 // This class allows to deal with macro two use-cases:
6925 // 1) fork() + exec() equivalent: for spawning a brand new process image.
6926 //    This happens when |args.exec_cmd| is not empty.
6927 //    This is safe to use even in a multi-threaded environment.
6928 // 2) fork(): for spawning a process and running a function.
6929 //    This happens when |args.posix_entrypoint_for_testing| is not empty.
6930 //    This is intended only for tests as it is extremely subtle.
6931 //    This mode must be used with extreme care. Before the entrypoint is
6932 //    invoked all file descriptors other than stdin/out/err and the ones
6933 //    specified in |args.preserve_fds| will be closed, to avoid each process
6934 //    retaining a dupe of other subprocesses pipes. This however means that
6935 //    any non trivial calls (including logging) must be avoided as they might
6936 //    refer to FDs that are now closed. The entrypoint should really be used
6937 //    just to signal a pipe or similar for synchronizing sequencing in tests.
6938 
6939 //
6940 // This class allows to control stdin/out/err pipe redirection and takes care
6941 // of keeping all the pipes pumped (stdin) / drained (stdout/err), in a similar
6942 // fashion of python's subprocess.Communicate()
6943 // stdin: is always piped and closed once the |args.input| buffer is written.
6944 // stdout/err can be either:
6945 //   - dup()ed onto the parent process stdout/err.
6946 //   - redirected onto /dev/null.
6947 //   - piped onto a buffer (see output() method). There is only one output
6948 //     buffer in total. If both stdout and stderr are set to kBuffer mode, they
6949 //     will be merged onto the same. There doesn't seem any use case where they
6950 //     are needed distinctly.
6951 //
6952 // Some caveats worth mentioning:
6953 // - It always waitpid()s, to avoid leaving zombies around. If the process is
6954 //   not terminated by the time the destructor is reached, the dtor will
6955 //   send a SIGKILL and wait for the termination.
6956 // - After fork()-ing it will close all file descriptors, preserving only
6957 //   stdin/out/err and the fds listed in |args.preserve_fds|.
6958 // - On Linux/Android, the child process will be SIGKILL-ed if the calling
6959 //   thread exists, even if the Subprocess is std::move()-d onto another thread.
6960 //   This happens by virtue PR_SET_PDEATHSIG, which is used to avoid that
6961 //   child processes are leaked in the case of a crash of the parent (frequent
6962 //   in tests). However, the child process might still be leaked if execing
6963 //   a setuid/setgid binary (see man 2 prctl).
6964 //
6965 // Usage:
6966 // base::Subprocess p({"/bin/cat", "-"});
6967 // (or equivalently:
6968 //     base::Subprocess p;
6969 //     p.args.exec_cmd.push_back("/bin/cat");
6970 //     p.args.exec_cmd.push_back("-");
6971 //  )
6972 // p.args.stdout_mode = base::Subprocess::kBuffer;
6973 // p.args.stderr_mode = base::Subprocess::kInherit;
6974 // p.args.input = "stdin contents";
6975 // p.Call();
6976 // (or equivalently:
6977 //     p.Start();
6978 //     p.Wait();
6979 // )
6980 // EXPECT_EQ(p.status(), base::Subprocess::kTerminated);
6981 // EXPECT_EQ(p.returncode(), 0);
6982 class Subprocess {
6983  public:
6984   enum Status {
6985     kNotStarted = 0,  // Before calling Start() or Call().
6986     kRunning,         // After calling Start(), before Wait().
6987     kTerminated,      // The subprocess terminated, either successfully or not.
6988                       // This includes crashes or other signals on UNIX.
6989   };
6990 
6991   enum OutputMode {
6992     kInherit = 0,  // Inherit's the caller process stdout/stderr.
6993     kDevNull,      // dup() onto /dev/null
6994     kBuffer,       // dup() onto a pipe and move it into the output() buffer.
6995     kFd,           // dup() onto the passed args.fd.
6996   };
6997 
6998   // Input arguments for configuring the subprocess behavior.
6999   struct Args {
Argsperfetto::base::Subprocess::Args7000     Args(std::initializer_list<std::string> _cmd = {}) : exec_cmd(_cmd) {}
7001     Args(Args&&) noexcept;
7002     Args& operator=(Args&&);
7003     // If non-empty this will cause an exec() when Start()/Call() are called.
7004     std::vector<std::string> exec_cmd;
7005 
7006 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
7007     // If non-empty, it changes the argv[0] argument passed to exec. If
7008     // unset, argv[0] == exec_cmd[0]. This is to handle cases like:
7009     // exec_cmd = {"/proc/self/exec"}, argv0: "my_custom_test_override".
7010     std::string posix_argv0_override_for_testing;
7011 
7012     // If non-empty this will be invoked on the fork()-ed child process, after
7013     // stdin/out/err has been redirected and all other file descriptor are
7014     // closed. It is valid to specify both |exec_cmd| AND
7015     // |posix_entrypoint_for_testing|. In this case the latter will be invoked
7016     // just before the exec() call, but after having closed all fds % stdin/o/e.
7017     // This is for synchronization barriers in tests.
7018     std::function<void()> posix_entrypoint_for_testing;
7019 #endif
7020 
7021     // If non-empty, replaces the environment passed to exec().
7022     std::vector<std::string> env;
7023 
7024     // The file descriptors in this list will not be closed.
7025     std::vector<int> preserve_fds;
7026 
7027     // The data to push in the child process stdin.
7028     std::string input;
7029 
7030     OutputMode stdout_mode = kInherit;
7031     OutputMode stderr_mode = kInherit;
7032 
7033     base::ScopedPlatformHandle out_fd;
7034 
7035     // Returns " ".join(exec_cmd), quoting arguments.
7036     std::string GetCmdString() const;
7037   };
7038 
7039   struct ResourceUsage {
7040     uint32_t cpu_utime_ms = 0;
7041     uint32_t cpu_stime_ms = 0;
7042     uint32_t max_rss_kb = 0;
7043     uint32_t min_page_faults = 0;
7044     uint32_t maj_page_faults = 0;
7045     uint32_t vol_ctx_switch = 0;
7046     uint32_t invol_ctx_switch = 0;
7047 
cpu_time_msperfetto::base::Subprocess::ResourceUsage7048     uint32_t cpu_time_ms() const { return cpu_utime_ms + cpu_stime_ms; }
7049   };
7050 
7051   explicit Subprocess(std::initializer_list<std::string> exec_cmd = {});
7052   Subprocess(Subprocess&&) noexcept;
7053   Subprocess& operator=(Subprocess&&);
7054   ~Subprocess();  // It will KillAndWaitForTermination() if still alive.
7055 
7056   // Starts the subprocess but doesn't wait for its termination. The caller
7057   // is expected to either call Wait() or Poll() after this call.
7058   void Start();
7059 
7060   // Wait for process termination. Can be called more than once.
7061   // Args:
7062   //   |timeout_ms| = 0: wait indefinitely.
7063   //   |timeout_ms| > 0: wait for at most |timeout_ms|.
7064   // Returns:
7065   //  True: The process terminated. See status() and returncode().
7066   //  False: Timeout reached, the process is still running. In this case the
7067   //         process will be left in the kRunning state.
7068   bool Wait(int timeout_ms = 0);
7069 
7070   // Equivalent of Start() + Wait();
7071   // Returns true if the process exited cleanly with return code 0. False in
7072   // any othe case.
7073   bool Call(int timeout_ms = 0);
7074 
7075   Status Poll();
7076 
7077   // Sends a signal (SIGKILL if not specified) and wait for process termination.
7078   void KillAndWaitForTermination(int sig_num = 0);
7079 
pid() const7080   PlatformProcessId pid() const { return s_->pid; }
7081 
7082   // The accessors below are updated only after a call to Poll(), Wait() or
7083   // KillAndWaitForTermination().
7084   // In most cases you want to call Poll() rather than these accessors.
7085 
status() const7086   Status status() const { return s_->status; }
returncode() const7087   int returncode() const { return s_->returncode; }
timed_out() const7088   bool timed_out() const { return s_->timed_out; }
7089 
7090   // This contains both stdout and stderr (if the corresponding _mode ==
7091   // kBuffer). It's non-const so the caller can std::move() it.
output()7092   std::string& output() { return s_->output; }
output() const7093   const std::string& output() const { return s_->output; }
7094 
posix_rusage() const7095   const ResourceUsage& posix_rusage() const { return *s_->rusage; }
7096 
7097   Args args;
7098 
7099  private:
7100   // The signal/exit code used when killing the process in case of a timeout.
7101   static const int kTimeoutSignal;
7102 
7103   Subprocess(const Subprocess&) = delete;
7104   Subprocess& operator=(const Subprocess&) = delete;
7105 
7106   // This is to deal robustly with the move operators, without having to
7107   // manually maintain member-wise move instructions.
7108   struct MovableState {
7109     base::Pipe stdin_pipe;
7110     base::Pipe stdouterr_pipe;
7111     PlatformProcessId pid;
7112     Status status = kNotStarted;
7113     int returncode = -1;
7114     std::string output;  // Stdin+stderr. Only when kBuffer.
7115     std::unique_ptr<ResourceUsage> rusage{new ResourceUsage()};
7116     bool timed_out = false;
7117 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
7118     std::thread stdouterr_thread;
7119     std::thread stdin_thread;
7120     ScopedPlatformHandle win_proc_handle;
7121     ScopedPlatformHandle win_thread_handle;
7122 
7123     base::EventFd stdouterr_done_event;
7124     std::mutex mutex;  // Protects locked_outerr_buf and the two pipes.
7125     std::string locked_outerr_buf;
7126 #else
7127     base::Pipe exit_status_pipe;
7128     size_t input_written = 0;
7129     std::thread waitpid_thread;
7130 #endif
7131   };
7132 
7133 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
7134   static void StdinThread(MovableState*, std::string input);
7135   static void StdoutErrThread(MovableState*);
7136 #else
7137   void TryPushStdin();
7138   void TryReadStdoutAndErr();
7139   void TryReadExitStatus();
7140   void KillAtMostOnce();
7141   bool PollInternal(int poll_timeout_ms);
7142 #endif
7143 
7144   std::unique_ptr<MovableState> s_;
7145 };
7146 
7147 }  // namespace base
7148 }  // namespace perfetto
7149 
7150 #endif  // INCLUDE_PERFETTO_EXT_BASE_SUBPROCESS_H_
7151 /*
7152  * Copyright (C) 2020 The Android Open Source Project
7153  *
7154  * Licensed under the Apache License, Version 2.0 (the "License");
7155  * you may not use this file except in compliance with the License.
7156  * You may obtain a copy of the License at
7157  *
7158  *      http://www.apache.org/licenses/LICENSE-2.0
7159  *
7160  * Unless required by applicable law or agreed to in writing, software
7161  * distributed under the License is distributed on an "AS IS" BASIS,
7162  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7163  * See the License for the specific language governing permissions and
7164  * limitations under the License.
7165  */
7166 
7167 // gen_amalgamated expanded: #include "perfetto/ext/base/subprocess.h"
7168 
7169 #include <tuple>
7170 
7171 // This file contains only the common bits (ctors / dtors / move operators).
7172 // The rest lives in subprocess_posix.cc and subprocess_windows.cc.
7173 
7174 namespace perfetto {
7175 namespace base {
7176 
7177 Subprocess::Args::Args(Args&&) noexcept = default;
7178 Subprocess::Args& Subprocess::Args::operator=(Args&&) = default;
7179 
Subprocess(std::initializer_list<std::string> a)7180 Subprocess::Subprocess(std::initializer_list<std::string> a)
7181     : args(a), s_(new MovableState()) {}
7182 
Subprocess(Subprocess && other)7183 Subprocess::Subprocess(Subprocess&& other) noexcept {
7184   static_assert(sizeof(Subprocess) ==
7185                     sizeof(std::tuple<std::unique_ptr<MovableState>, Args>),
7186                 "base::Subprocess' move ctor needs updating");
7187   s_ = std::move(other.s_);
7188   args = std::move(other.args);
7189 
7190   // Reset the state of the moved-from object.
7191   other.s_.reset(new MovableState());
7192   other.~Subprocess();
7193   new (&other) Subprocess();
7194 }
7195 
operator =(Subprocess && other)7196 Subprocess& Subprocess::operator=(Subprocess&& other) {
7197   this->~Subprocess();
7198   new (this) Subprocess(std::move(other));
7199   return *this;
7200 }
7201 
~Subprocess()7202 Subprocess::~Subprocess() {
7203   if (s_->status == kRunning)
7204     KillAndWaitForTermination();
7205 }
7206 
Call(int timeout_ms)7207 bool Subprocess::Call(int timeout_ms) {
7208   PERFETTO_CHECK(s_->status == kNotStarted);
7209   Start();
7210 
7211   if (!Wait(timeout_ms)) {
7212     s_->timed_out = true;
7213     KillAndWaitForTermination(kTimeoutSignal);
7214   }
7215   PERFETTO_DCHECK(s_->status != kRunning);
7216   return s_->status == kTerminated && s_->returncode == 0;
7217 }
7218 
GetCmdString() const7219 std::string Subprocess::Args::GetCmdString() const {
7220   std::string str;
7221   for (size_t i = 0; i < exec_cmd.size(); i++) {
7222     str += i > 0 ? " \"" : "";
7223     str += exec_cmd[i];
7224     str += i > 0 ? "\"" : "";
7225   }
7226   return str;
7227 }
7228 
7229 }  // namespace base
7230 }  // namespace perfetto
7231 // gen_amalgamated begin source: src/base/subprocess_posix.cc
7232 /*
7233  * Copyright (C) 2020 The Android Open Source Project
7234  *
7235  * Licensed under the Apache License, Version 2.0 (the "License");
7236  * you may not use this file except in compliance with the License.
7237  * You may obtain a copy of the License at
7238  *
7239  *      http://www.apache.org/licenses/LICENSE-2.0
7240  *
7241  * Unless required by applicable law or agreed to in writing, software
7242  * distributed under the License is distributed on an "AS IS" BASIS,
7243  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7244  * See the License for the specific language governing permissions and
7245  * limitations under the License.
7246  */
7247 
7248 // gen_amalgamated expanded: #include "perfetto/ext/base/subprocess.h"
7249 
7250 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
7251 
7252 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
7253     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
7254     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
7255 
7256 #include <fcntl.h>
7257 #include <poll.h>
7258 #include <signal.h>
7259 #include <stdio.h>
7260 #include <sys/resource.h>
7261 #include <sys/types.h>
7262 #include <sys/wait.h>
7263 #include <unistd.h>
7264 
7265 #include <algorithm>
7266 #include <thread>
7267 #include <tuple>
7268 
7269 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
7270     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
7271 #include <sys/prctl.h>
7272 #endif
7273 
7274 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
7275 // gen_amalgamated expanded: #include "perfetto/base/time.h"
7276 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
7277 
7278 // In MacOS this is not defined in any header.
7279 extern "C" char** environ;
7280 
7281 namespace perfetto {
7282 namespace base {
7283 
7284 namespace {
7285 
7286 struct ChildProcessArgs {
7287   Subprocess::Args* create_args;
7288   const char* exec_cmd = nullptr;
7289   std::vector<char*> argv;
7290   std::vector<char*> env;
7291   int stdin_pipe_rd = -1;
7292   int stdouterr_pipe_wr = -1;
7293 };
7294 
7295 // Don't add any dynamic allocation in this function. This will be invoked
7296 // under a fork(), potentially in a state where the allocator lock is held.
ChildProcess(ChildProcessArgs * args)7297 void __attribute__((noreturn)) ChildProcess(ChildProcessArgs* args) {
7298 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
7299     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
7300   // In no case we want a child process to outlive its parent process. This is
7301   // relevant for tests, so that a test failure/crash doesn't leave child
7302   // processes around that get reparented to init.
7303   prctl(PR_SET_PDEATHSIG, SIGKILL);
7304 #endif
7305 
7306   auto die = [args](const char* err) __attribute__((noreturn)) {
7307     base::ignore_result(write(args->stdouterr_pipe_wr, err, strlen(err)));
7308     base::ignore_result(write(args->stdouterr_pipe_wr, "\n", 1));
7309     // From https://www.gnu.org/software/libc/manual/html_node/Exit-Status.html
7310     // "In particular, the value 128 is used to indicate failure to execute
7311     // another program in a subprocess. This convention is not universally
7312     // obeyed, but it is a good idea to follow it in your programs."
7313     _exit(128);
7314   };
7315 
7316   auto set_fd_close_on_exec = [&die](int fd, bool close_on_exec) {
7317     int flags = fcntl(fd, F_GETFD, 0);
7318     if (flags < 0)
7319       die("fcntl(F_GETFD) failed");
7320     flags = close_on_exec ? (flags | FD_CLOEXEC) : (flags & ~FD_CLOEXEC);
7321     if (fcntl(fd, F_SETFD, flags) < 0)
7322       die("fcntl(F_SETFD) failed");
7323   };
7324 
7325   if (getppid() == 1)
7326     die("terminating because parent process died");
7327 
7328   if (dup2(args->stdin_pipe_rd, STDIN_FILENO) == -1)
7329     die("Failed to dup2(STDIN)");
7330   close(args->stdin_pipe_rd);
7331 
7332   switch (args->create_args->stdout_mode) {
7333     case Subprocess::kInherit:
7334       break;
7335     case Subprocess::kDevNull: {
7336       if (dup2(open("/dev/null", O_RDWR), STDOUT_FILENO) == -1)
7337         die("Failed to dup2(STDOUT)");
7338       break;
7339     }
7340     case Subprocess::kBuffer:
7341       if (dup2(args->stdouterr_pipe_wr, STDOUT_FILENO) == -1)
7342         die("Failed to dup2(STDOUT)");
7343       break;
7344     case Subprocess::kFd:
7345       if (dup2(*args->create_args->out_fd, STDOUT_FILENO) == -1)
7346         die("Failed to dup2(STDOUT)");
7347       break;
7348   }
7349 
7350   switch (args->create_args->stderr_mode) {
7351     case Subprocess::kInherit:
7352       break;
7353     case Subprocess::kDevNull: {
7354       if (dup2(open("/dev/null", O_RDWR), STDERR_FILENO) == -1)
7355         die("Failed to dup2(STDERR)");
7356       break;
7357     }
7358     case Subprocess::kBuffer:
7359       if (dup2(args->stdouterr_pipe_wr, STDERR_FILENO) == -1)
7360         die("Failed to dup2(STDERR)");
7361       break;
7362     case Subprocess::kFd:
7363       if (dup2(*args->create_args->out_fd, STDERR_FILENO) == -1)
7364         die("Failed to dup2(STDERR)");
7365       break;
7366   }
7367 
7368   // Close all FDs % stdin/out/err and the ones that the client explicitly
7369   // asked to retain. The reason for this is twofold:
7370   // 1. For exec-only (i.e. entrypoint == empty) cases: it avoids leaking FDs
7371   //    that didn't get marked as O_CLOEXEC by accident.
7372   // 2. In fork() mode (entrypoint not empty) avoids retaining a dup of eventfds
7373   //    that would prevent the parent process to receive EOFs (tests usually use
7374   //    pipes as a synchronization mechanism between subprocesses).
7375   const auto& preserve_fds = args->create_args->preserve_fds;
7376   for (int i = 0; i < 512; i++) {
7377     if (i != STDIN_FILENO && i != STDERR_FILENO && i != STDOUT_FILENO &&
7378         i != args->stdouterr_pipe_wr &&
7379         !std::count(preserve_fds.begin(), preserve_fds.end(), i)) {
7380       close(i);
7381     }
7382   }
7383 
7384   // Clears O_CLOEXEC from stdin/out/err. These are the only FDs that we want
7385   // to be preserved after the exec().
7386   set_fd_close_on_exec(STDIN_FILENO, false);
7387   set_fd_close_on_exec(STDOUT_FILENO, false);
7388   set_fd_close_on_exec(STDERR_FILENO, false);
7389 
7390   // If the caller specified a std::function entrypoint, run that first.
7391   if (args->create_args->posix_entrypoint_for_testing)
7392     args->create_args->posix_entrypoint_for_testing();
7393 
7394   // If the caller specified only an entrypoint, without any args, exit now.
7395   // Otherwise proceed with the exec() below.
7396   if (!args->exec_cmd)
7397     _exit(0);
7398 
7399   // If |args[0]| is a path use execv() (which takes a path), othewise use
7400   // exevp(), which uses the shell and follows PATH.
7401   if (strchr(args->exec_cmd, '/')) {
7402     char** env = args->env.empty() ? environ : args->env.data();
7403     execve(args->exec_cmd, args->argv.data(), env);
7404   } else {
7405     // There is no execvpe() on Mac.
7406     if (!args->env.empty())
7407       die("A full path is required for |exec_cmd| when setting |env|");
7408     execvp(args->exec_cmd, args->argv.data());
7409   }
7410 
7411   // Reached only if execv fails.
7412   die("execve() failed");
7413 }
7414 
7415 }  // namespace
7416 
7417 // static
7418 const int Subprocess::kTimeoutSignal = SIGKILL;
7419 
Start()7420 void Subprocess::Start() {
7421   ChildProcessArgs proc_args;
7422   proc_args.create_args = &args;
7423 
7424   // Setup argv.
7425   if (!args.exec_cmd.empty()) {
7426     proc_args.exec_cmd = args.exec_cmd[0].c_str();
7427     for (const std::string& arg : args.exec_cmd)
7428       proc_args.argv.push_back(const_cast<char*>(arg.c_str()));
7429     proc_args.argv.push_back(nullptr);
7430 
7431     if (!args.posix_argv0_override_for_testing.empty()) {
7432       proc_args.argv[0] =
7433           const_cast<char*>(args.posix_argv0_override_for_testing.c_str());
7434     }
7435   }
7436 
7437   // Setup env.
7438   if (!args.env.empty()) {
7439     for (const std::string& str : args.env)
7440       proc_args.env.push_back(const_cast<char*>(str.c_str()));
7441     proc_args.env.push_back(nullptr);
7442   }
7443 
7444   // Setup the pipes for stdin/err redirection.
7445   s_->stdin_pipe = base::Pipe::Create(base::Pipe::kWrNonBlock);
7446   proc_args.stdin_pipe_rd = *s_->stdin_pipe.rd;
7447   s_->stdouterr_pipe = base::Pipe::Create(base::Pipe::kRdNonBlock);
7448   proc_args.stdouterr_pipe_wr = *s_->stdouterr_pipe.wr;
7449 
7450   // Spawn the child process that will exec().
7451   s_->pid = fork();
7452   PERFETTO_CHECK(s_->pid >= 0);
7453   if (s_->pid == 0) {
7454     // Close the parent-ends of the pipes.
7455     s_->stdin_pipe.wr.reset();
7456     s_->stdouterr_pipe.rd.reset();
7457     ChildProcess(&proc_args);
7458     // ChildProcess() doesn't return, not even in case of failures.
7459     PERFETTO_FATAL("not reached");
7460   }
7461 
7462   s_->status = kRunning;
7463 
7464   // Close the child-end of the pipes.
7465   // Deliberately NOT closing the s_->stdin_pipe.rd. This is to avoid crashing
7466   // with a SIGPIPE if the process exits without consuming its stdin, while
7467   // the parent tries to write() on the other end of the stdin pipe.
7468   s_->stdouterr_pipe.wr.reset();
7469   proc_args.create_args->out_fd.reset();
7470 
7471   // Spawn a thread that is blocked on waitpid() and writes the termination
7472   // status onto a pipe. The problem here is that waipid() doesn't have a
7473   // timeout option and can't be passed to poll(). The alternative would be
7474   // using a SIGCHLD handler, but anecdotally signal handlers introduce more
7475   // problems than what they solve.
7476   s_->exit_status_pipe = base::Pipe::Create(base::Pipe::kRdNonBlock);
7477 
7478   // Both ends of the pipe are closed after the thread.join().
7479   int pid = s_->pid;
7480   int exit_status_pipe_wr = s_->exit_status_pipe.wr.release();
7481   auto* rusage = s_->rusage.get();
7482   s_->waitpid_thread = std::thread([pid, exit_status_pipe_wr, rusage] {
7483     int pid_stat = -1;
7484     struct rusage usg {};
7485     int wait_res = PERFETTO_EINTR(wait4(pid, &pid_stat, 0, &usg));
7486     PERFETTO_CHECK(wait_res == pid);
7487 
7488     auto tv_to_ms = [](const struct timeval& tv) {
7489       return static_cast<uint32_t>(tv.tv_sec * 1000 + tv.tv_usec / 1000);
7490     };
7491     rusage->cpu_utime_ms = tv_to_ms(usg.ru_utime);
7492     rusage->cpu_stime_ms = tv_to_ms(usg.ru_stime);
7493     rusage->max_rss_kb = static_cast<uint32_t>(usg.ru_maxrss) / 1000;
7494     rusage->min_page_faults = static_cast<uint32_t>(usg.ru_minflt);
7495     rusage->maj_page_faults = static_cast<uint32_t>(usg.ru_majflt);
7496     rusage->vol_ctx_switch = static_cast<uint32_t>(usg.ru_nvcsw);
7497     rusage->invol_ctx_switch = static_cast<uint32_t>(usg.ru_nivcsw);
7498 
7499     base::ignore_result(PERFETTO_EINTR(
7500         write(exit_status_pipe_wr, &pid_stat, sizeof(pid_stat))));
7501     PERFETTO_CHECK(close(exit_status_pipe_wr) == 0 || errno == EINTR);
7502   });
7503 }
7504 
Poll()7505 Subprocess::Status Subprocess::Poll() {
7506   if (s_->status != kRunning)
7507     return s_->status;  // Nothing to poll.
7508   while (PollInternal(0 /* don't block*/)) {
7509   }
7510   return s_->status;
7511 }
7512 
7513 // |timeout_ms| semantic:
7514 //   -1: Block indefinitely.
7515 //    0: Don't block, return immediately.
7516 //   >0: Block for at most X ms.
7517 // Returns:
7518 //  True: Read at least one fd (so there might be more queued).
7519 //  False: if all fds reached quiescent (no data to read/write).
PollInternal(int poll_timeout_ms)7520 bool Subprocess::PollInternal(int poll_timeout_ms) {
7521   struct pollfd fds[3]{};
7522   size_t num_fds = 0;
7523   if (s_->exit_status_pipe.rd) {
7524     fds[num_fds].fd = *s_->exit_status_pipe.rd;
7525     fds[num_fds].events = POLLIN;
7526     num_fds++;
7527   }
7528   if (s_->stdouterr_pipe.rd) {
7529     fds[num_fds].fd = *s_->stdouterr_pipe.rd;
7530     fds[num_fds].events = POLLIN;
7531     num_fds++;
7532   }
7533   if (s_->stdin_pipe.wr) {
7534     fds[num_fds].fd = *s_->stdin_pipe.wr;
7535     fds[num_fds].events = POLLOUT;
7536     num_fds++;
7537   }
7538 
7539   if (num_fds == 0)
7540     return false;
7541 
7542   auto nfds = static_cast<nfds_t>(num_fds);
7543   int poll_res = PERFETTO_EINTR(poll(fds, nfds, poll_timeout_ms));
7544   PERFETTO_CHECK(poll_res >= 0);
7545 
7546   TryReadStdoutAndErr();
7547   TryPushStdin();
7548   TryReadExitStatus();
7549 
7550   return poll_res > 0;
7551 }
7552 
Wait(int timeout_ms)7553 bool Subprocess::Wait(int timeout_ms) {
7554   PERFETTO_CHECK(s_->status != kNotStarted);
7555 
7556   // Break out of the loop only after both conditions are satisfied:
7557   // - All stdout/stderr data has been read (if kBuffer).
7558   // - The process exited.
7559   // Note that the two events can happen arbitrary order. After the process
7560   // exits, there might be still data in the pipe buffer, which we want to
7561   // read fully.
7562   //
7563   // Instead, don't wait on the stdin to be fully written. The child process
7564   // might exit prematurely (or crash). If that happens, we can end up in a
7565   // state where the write(stdin_pipe_.wr) will never unblock.
7566 
7567   const int64_t t_start = base::GetWallTimeMs().count();
7568   while (s_->exit_status_pipe.rd || s_->stdouterr_pipe.rd) {
7569     int poll_timeout_ms = -1;  // Block until a FD is ready.
7570     if (timeout_ms > 0) {
7571       const int64_t now = GetWallTimeMs().count();
7572       poll_timeout_ms = timeout_ms - static_cast<int>(now - t_start);
7573       if (poll_timeout_ms <= 0)
7574         return false;
7575     }
7576     PollInternal(poll_timeout_ms);
7577   }  // while(...)
7578   return true;
7579 }
7580 
TryReadExitStatus()7581 void Subprocess::TryReadExitStatus() {
7582   if (!s_->exit_status_pipe.rd)
7583     return;
7584 
7585   int pid_stat = -1;
7586   int64_t rsize = PERFETTO_EINTR(
7587       read(*s_->exit_status_pipe.rd, &pid_stat, sizeof(pid_stat)));
7588   if (rsize < 0 && errno == EAGAIN)
7589     return;
7590 
7591   if (rsize > 0) {
7592     PERFETTO_CHECK(rsize == sizeof(pid_stat));
7593   } else if (rsize < 0) {
7594     PERFETTO_PLOG("Subprocess read(s_->exit_status_pipe) failed");
7595   }
7596   s_->waitpid_thread.join();
7597   s_->exit_status_pipe.rd.reset();
7598 
7599   s_->status = kTerminated;
7600   if (WIFEXITED(pid_stat)) {
7601     s_->returncode = WEXITSTATUS(pid_stat);
7602   } else if (WIFSIGNALED(pid_stat)) {
7603     s_->returncode = 128 + WTERMSIG(pid_stat);  // Follow bash convention.
7604   } else {
7605     PERFETTO_FATAL("waitpid() returned an unexpected value (0x%x)", pid_stat);
7606   }
7607 }
7608 
7609 // If the stidn pipe is still open, push input data and close it at the end.
TryPushStdin()7610 void Subprocess::TryPushStdin() {
7611   if (!s_->stdin_pipe.wr)
7612     return;
7613 
7614   PERFETTO_DCHECK(args.input.empty() || s_->input_written < args.input.size());
7615   if (!args.input.empty()) {
7616     int64_t wsize =
7617         PERFETTO_EINTR(write(*s_->stdin_pipe.wr, &args.input[s_->input_written],
7618                              args.input.size() - s_->input_written));
7619     if (wsize < 0 && errno == EAGAIN)
7620       return;
7621 
7622     if (wsize >= 0) {
7623       // Whether write() can return 0 is one of the greatest mysteries of UNIX.
7624       // Just ignore it.
7625       s_->input_written += static_cast<size_t>(wsize);
7626     } else {
7627       PERFETTO_PLOG("Subprocess write(stdin) failed");
7628       s_->stdin_pipe.wr.reset();
7629     }
7630   }
7631   PERFETTO_DCHECK(s_->input_written <= args.input.size());
7632   if (s_->input_written == args.input.size())
7633     s_->stdin_pipe.wr.reset();  // Close stdin.
7634 }
7635 
TryReadStdoutAndErr()7636 void Subprocess::TryReadStdoutAndErr() {
7637   if (!s_->stdouterr_pipe.rd)
7638     return;
7639   char buf[4096];
7640   int64_t rsize =
7641       PERFETTO_EINTR(read(*s_->stdouterr_pipe.rd, buf, sizeof(buf)));
7642   if (rsize < 0 && errno == EAGAIN)
7643     return;
7644 
7645   if (rsize > 0) {
7646     s_->output.append(buf, static_cast<size_t>(rsize));
7647   } else if (rsize == 0 /* EOF */) {
7648     s_->stdouterr_pipe.rd.reset();
7649   } else {
7650     PERFETTO_PLOG("Subprocess read(stdout/err) failed");
7651     s_->stdouterr_pipe.rd.reset();
7652   }
7653 }
7654 
KillAndWaitForTermination(int sig_num)7655 void Subprocess::KillAndWaitForTermination(int sig_num) {
7656   kill(s_->pid, sig_num ? sig_num : SIGKILL);
7657   Wait();
7658   // TryReadExitStatus must have joined the thread.
7659   PERFETTO_DCHECK(!s_->waitpid_thread.joinable());
7660 }
7661 
7662 }  // namespace base
7663 }  // namespace perfetto
7664 
7665 #endif  // PERFETTO_OS_LINUX || PERFETTO_OS_ANDROID || PERFETTO_OS_APPLE
7666 // gen_amalgamated begin source: src/base/subprocess_windows.cc
7667 /*
7668  * Copyright (C) 2020 The Android Open Source Project
7669  *
7670  * Licensed under the Apache License, Version 2.0 (the "License");
7671  * you may not use this file except in compliance with the License.
7672  * You may obtain a copy of the License at
7673  *
7674  *      http://www.apache.org/licenses/LICENSE-2.0
7675  *
7676  * Unless required by applicable law or agreed to in writing, software
7677  * distributed under the License is distributed on an "AS IS" BASIS,
7678  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7679  * See the License for the specific language governing permissions and
7680  * limitations under the License.
7681  */
7682 
7683 // gen_amalgamated expanded: #include "perfetto/ext/base/subprocess.h"
7684 
7685 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
7686 
7687 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
7688 
7689 #include <stdio.h>
7690 
7691 #include <algorithm>
7692 #include <mutex>
7693 #include <tuple>
7694 
7695 #include <Windows.h>
7696 
7697 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
7698 // gen_amalgamated expanded: #include "perfetto/base/time.h"
7699 // gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
7700 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
7701 
7702 namespace perfetto {
7703 namespace base {
7704 
7705 // static
7706 const int Subprocess::kTimeoutSignal = static_cast<int>(STATUS_TIMEOUT);
7707 
Start()7708 void Subprocess::Start() {
7709   if (args.exec_cmd.empty()) {
7710     PERFETTO_ELOG("Subprocess.exec_cmd cannot be empty on Windows");
7711     return;
7712   }
7713 
7714   // Quote arguments but only when ambiguous. When quoting, CreateProcess()
7715   // assumes that the command is an absolute path and does not search in the
7716   // %PATH%. If non quoted, instead, CreateProcess() tries both. This is to
7717   // allow Subprocess("cmd.exe", "/c", "shell command").
7718   std::string cmd;
7719   for (const auto& part : args.exec_cmd) {
7720     if (part.find(" ") != std::string::npos) {
7721       cmd += "\"" + part + "\" ";
7722     } else {
7723       cmd += part + " ";
7724     }
7725   }
7726   // Remove trailing space.
7727   if (!cmd.empty())
7728     cmd.resize(cmd.size() - 1);
7729 
7730   s_->stdin_pipe = Pipe::Create();
7731   // Allow the child process to inherit the other end of the pipe.
7732   PERFETTO_CHECK(
7733       ::SetHandleInformation(*s_->stdin_pipe.rd, HANDLE_FLAG_INHERIT, 1));
7734 
7735   if (args.stderr_mode == kBuffer || args.stdout_mode == kBuffer) {
7736     s_->stdouterr_pipe = Pipe::Create();
7737     PERFETTO_CHECK(
7738         ::SetHandleInformation(*s_->stdouterr_pipe.wr, HANDLE_FLAG_INHERIT, 1));
7739   }
7740 
7741   ScopedPlatformHandle nul_handle;
7742   if (args.stderr_mode == kDevNull || args.stdout_mode == kDevNull) {
7743     nul_handle.reset(::CreateFileA("NUL", GENERIC_WRITE, FILE_SHARE_WRITE,
7744                                    nullptr, OPEN_EXISTING,
7745                                    FILE_ATTRIBUTE_NORMAL, nullptr));
7746     PERFETTO_CHECK(::SetHandleInformation(*nul_handle, HANDLE_FLAG_INHERIT, 1));
7747   }
7748 
7749   PROCESS_INFORMATION proc_info{};
7750   STARTUPINFOA start_info{};
7751   start_info.cb = sizeof(STARTUPINFOA);
7752 
7753   if (args.stderr_mode == kInherit) {
7754     start_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE);
7755   } else if (args.stderr_mode == kBuffer) {
7756     start_info.hStdError = *s_->stdouterr_pipe.wr;
7757   } else if (args.stderr_mode == kDevNull) {
7758     start_info.hStdError = *nul_handle;
7759   } else if (args.stderr_mode == kFd) {
7760     PERFETTO_CHECK(
7761         ::SetHandleInformation(*args.out_fd, HANDLE_FLAG_INHERIT, 1));
7762     start_info.hStdError = *args.out_fd;
7763   } else {
7764     PERFETTO_CHECK(false);
7765   }
7766 
7767   if (args.stdout_mode == kInherit) {
7768     start_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE);
7769   } else if (args.stdout_mode == kBuffer) {
7770     start_info.hStdOutput = *s_->stdouterr_pipe.wr;
7771   } else if (args.stdout_mode == kDevNull) {
7772     start_info.hStdOutput = *nul_handle;
7773   } else if (args.stdout_mode == kFd) {
7774     PERFETTO_CHECK(
7775         ::SetHandleInformation(*args.out_fd, HANDLE_FLAG_INHERIT, 1));
7776     start_info.hStdOutput = *args.out_fd;
7777   } else {
7778     PERFETTO_CHECK(false);
7779   }
7780 
7781   start_info.hStdInput = *s_->stdin_pipe.rd;
7782   start_info.dwFlags |= STARTF_USESTDHANDLES;
7783 
7784   // Create the child process.
7785   bool success =
7786       ::CreateProcessA(nullptr,      // App name. Needs to be null to use PATH.
7787                        &cmd[0],      // Command line.
7788                        nullptr,      // Process security attributes.
7789                        nullptr,      // Primary thread security attributes.
7790                        true,         // Handles are inherited.
7791                        0,            // Flags.
7792                        nullptr,      // Use parent's environment.
7793                        nullptr,      // Use parent's current directory.
7794                        &start_info,  // STARTUPINFO pointer.
7795                        &proc_info);  // Receives PROCESS_INFORMATION.
7796 
7797   // Close on our side the pipe ends that we passed to the child process.
7798   s_->stdin_pipe.rd.reset();
7799   s_->stdouterr_pipe.wr.reset();
7800   args.out_fd.reset();
7801 
7802   if (!success) {
7803     s_->returncode = ERROR_FILE_NOT_FOUND;
7804     s_->status = kTerminated;
7805     s_->stdin_pipe.wr.reset();
7806     s_->stdouterr_pipe.rd.reset();
7807     PERFETTO_ELOG("CreateProcess failed: %lx, cmd: %s", GetLastError(),
7808                   &cmd[0]);
7809     return;
7810   }
7811 
7812   s_->pid = proc_info.dwProcessId;
7813   s_->win_proc_handle = ScopedPlatformHandle(proc_info.hProcess);
7814   s_->win_thread_handle = ScopedPlatformHandle(proc_info.hThread);
7815   s_->status = kRunning;
7816 
7817   MovableState* s = s_.get();
7818   s_->stdin_thread = std::thread(&Subprocess::StdinThread, s, args.input);
7819 
7820   if (args.stderr_mode == kBuffer || args.stdout_mode == kBuffer) {
7821     PERFETTO_DCHECK(s_->stdouterr_pipe.rd);
7822     s_->stdouterr_thread = std::thread(&Subprocess::StdoutErrThread, s);
7823   }
7824 }
7825 
7826 // static
StdinThread(MovableState * s,std::string input)7827 void Subprocess::StdinThread(MovableState* s, std::string input) {
7828   size_t input_written = 0;
7829   while (input_written < input.size()) {
7830     DWORD wsize = 0;
7831     if (::WriteFile(*s->stdin_pipe.wr, input.data() + input_written,
7832                     static_cast<DWORD>(input.size() - input_written), &wsize,
7833                     nullptr)) {
7834       input_written += wsize;
7835     } else {
7836       // ERROR_BROKEN_PIPE is WAI when the child just closes stdin and stops
7837       // accepting input.
7838       auto err = ::GetLastError();
7839       if (err != ERROR_BROKEN_PIPE)
7840         PERFETTO_PLOG("Subprocess WriteFile(stdin) failed %lx", err);
7841       break;
7842     }
7843   }  // while(...)
7844   std::unique_lock<std::mutex> lock(s->mutex);
7845   s->stdin_pipe.wr.reset();
7846 }
7847 
7848 // static
StdoutErrThread(MovableState * s)7849 void Subprocess::StdoutErrThread(MovableState* s) {
7850   char buf[4096];
7851   for (;;) {
7852     DWORD rsize = 0;
7853     bool res =
7854         ::ReadFile(*s->stdouterr_pipe.rd, buf, sizeof(buf), &rsize, nullptr);
7855     if (!res) {
7856       auto err = GetLastError();
7857       if (err != ERROR_BROKEN_PIPE)
7858         PERFETTO_PLOG("Subprocess ReadFile(stdouterr) failed %ld", err);
7859     }
7860 
7861     if (rsize > 0) {
7862       std::unique_lock<std::mutex> lock(s->mutex);
7863       s->locked_outerr_buf.append(buf, static_cast<size_t>(rsize));
7864     } else {  // EOF or some error.
7865       break;
7866     }
7867   }  // For(..)
7868 
7869   // Close the stdouterr_pipe. The main loop looks at the pipe closure to
7870   // determine whether the stdout/err thread has completed.
7871   {
7872     std::unique_lock<std::mutex> lock(s->mutex);
7873     s->stdouterr_pipe.rd.reset();
7874   }
7875   s->stdouterr_done_event.Notify();
7876 }
7877 
Poll()7878 Subprocess::Status Subprocess::Poll() {
7879   if (s_->status != kRunning)
7880     return s_->status;  // Nothing to poll.
7881   Wait(1 /*ms*/);
7882   return s_->status;
7883 }
7884 
Wait(int timeout_ms)7885 bool Subprocess::Wait(int timeout_ms) {
7886   PERFETTO_CHECK(s_->status != kNotStarted);
7887   const bool wait_forever = timeout_ms == 0;
7888   const int64_t wait_start_ms = base::GetWallTimeMs().count();
7889 
7890   // Break out of the loop only after both conditions are satisfied:
7891   // - All stdout/stderr data has been read (if kBuffer).
7892   // - The process exited.
7893   // Note that the two events can happen arbitrary order. After the process
7894   // exits, there might be still data in the pipe buffer, which we want to
7895   // read fully.
7896   // Note also that stdout/err might be "complete" before starting, if neither
7897   // is operating in kBuffer mode. In that case we just want to wait for the
7898   // process termination.
7899   //
7900   // Instead, don't wait on the stdin to be fully written. The child process
7901   // might exit prematurely (or crash). If that happens, we can end up in a
7902   // state where the write(stdin_pipe_.wr) will never unblock.
7903   bool stdouterr_complete = false;
7904   for (;;) {
7905     HANDLE wait_handles[2]{};
7906     DWORD num_handles = 0;
7907 
7908     // Check if the process exited.
7909     bool process_exited = !s_->win_proc_handle;
7910     if (!process_exited) {
7911       DWORD exit_code = STILL_ACTIVE;
7912       PERFETTO_CHECK(::GetExitCodeProcess(*s_->win_proc_handle, &exit_code));
7913       if (exit_code != STILL_ACTIVE) {
7914         s_->returncode = static_cast<int>(exit_code);
7915         s_->status = kTerminated;
7916         s_->win_proc_handle.reset();
7917         s_->win_thread_handle.reset();
7918         process_exited = true;
7919       }
7920     } else {
7921       PERFETTO_DCHECK(s_->status != kRunning);
7922     }
7923     if (!process_exited) {
7924       wait_handles[num_handles++] = *s_->win_proc_handle;
7925     }
7926 
7927     // Check if there is more output and if the stdout/err pipe has been closed.
7928     {
7929       std::unique_lock<std::mutex> lock(s_->mutex);
7930       // Move the output from the internal buffer shared with the
7931       // stdouterr_thread to the final buffer exposed to the client.
7932       if (!s_->locked_outerr_buf.empty()) {
7933         s_->output.append(std::move(s_->locked_outerr_buf));
7934         s_->locked_outerr_buf.clear();
7935       }
7936       stdouterr_complete = !s_->stdouterr_pipe.rd;
7937       if (!stdouterr_complete) {
7938         wait_handles[num_handles++] = s_->stdouterr_done_event.fd();
7939       }
7940     }  // lock(s_->mutex)
7941 
7942     if (num_handles == 0) {
7943       PERFETTO_DCHECK(process_exited && stdouterr_complete);
7944       break;
7945     }
7946 
7947     DWORD wait_ms;  // Note: DWORD is unsigned.
7948     if (wait_forever) {
7949       wait_ms = INFINITE;
7950     } else {
7951       const int64_t now = GetWallTimeMs().count();
7952       const int64_t wait_left_ms = timeout_ms - (now - wait_start_ms);
7953       if (wait_left_ms <= 0)
7954         return false;  // Timed out
7955       wait_ms = static_cast<DWORD>(wait_left_ms);
7956     }
7957 
7958     auto wait_res =
7959         ::WaitForMultipleObjects(num_handles, wait_handles, false, wait_ms);
7960     PERFETTO_CHECK(wait_res != WAIT_FAILED);
7961   }
7962 
7963   PERFETTO_DCHECK(!s_->win_proc_handle);
7964   PERFETTO_DCHECK(!s_->win_thread_handle);
7965 
7966   if (s_->stdin_thread.joinable())  // Might not exist if CreateProcess failed.
7967     s_->stdin_thread.join();
7968   if (s_->stdouterr_thread.joinable())
7969     s_->stdouterr_thread.join();
7970 
7971   // The stdin pipe is closed by the dedicated stdin thread. However if that is
7972   // not started (e.g. because of no redirection) force close it now. Needs to
7973   // happen after the join() to be thread safe.
7974   s_->stdin_pipe.wr.reset();
7975   s_->stdouterr_pipe.rd.reset();
7976 
7977   return true;
7978 }
7979 
KillAndWaitForTermination(int exit_code)7980 void Subprocess::KillAndWaitForTermination(int exit_code) {
7981   auto code = exit_code ? static_cast<DWORD>(exit_code) : STATUS_CONTROL_C_EXIT;
7982   ::TerminateProcess(*s_->win_proc_handle, code);
7983   Wait();
7984   // TryReadExitStatus must have joined the threads.
7985   PERFETTO_DCHECK(!s_->stdin_thread.joinable());
7986   PERFETTO_DCHECK(!s_->stdouterr_thread.joinable());
7987 }
7988 
7989 }  // namespace base
7990 }  // namespace perfetto
7991 
7992 #endif  // PERFETTO_OS_WIN
7993 // gen_amalgamated begin source: src/protozero/field.cc
7994 /*
7995  * Copyright (C) 2019 The Android Open Source Project
7996  *
7997  * Licensed under the Apache License, Version 2.0 (the "License");
7998  * you may not use this file except in compliance with the License.
7999  * You may obtain a copy of the License at
8000  *
8001  *      http://www.apache.org/licenses/LICENSE-2.0
8002  *
8003  * Unless required by applicable law or agreed to in writing, software
8004  * distributed under the License is distributed on an "AS IS" BASIS,
8005  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8006  * See the License for the specific language governing permissions and
8007  * limitations under the License.
8008  */
8009 
8010 // gen_amalgamated expanded: #include "perfetto/protozero/field.h"
8011 
8012 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
8013 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
8014 
8015 #if !PERFETTO_IS_LITTLE_ENDIAN()
8016 // The memcpy() for fixed32/64 below needs to be adjusted if we want to
8017 // support big endian CPUs. There doesn't seem to be a compelling need today.
8018 #error Unimplemented for big endian archs.
8019 #endif
8020 
8021 namespace protozero {
8022 
8023 template <typename Container>
SerializeAndAppendToInternal(Container * dst) const8024 void Field::SerializeAndAppendToInternal(Container* dst) const {
8025   namespace pu = proto_utils;
8026   size_t initial_size = dst->size();
8027   dst->resize(initial_size + pu::kMaxSimpleFieldEncodedSize + size_);
8028   uint8_t* start = reinterpret_cast<uint8_t*>(&(*dst)[initial_size]);
8029   uint8_t* wptr = start;
8030   switch (type_) {
8031     case static_cast<int>(pu::ProtoWireType::kVarInt): {
8032       wptr = pu::WriteVarInt(pu::MakeTagVarInt(id_), wptr);
8033       wptr = pu::WriteVarInt(int_value_, wptr);
8034       break;
8035     }
8036     case static_cast<int>(pu::ProtoWireType::kFixed32): {
8037       wptr = pu::WriteVarInt(pu::MakeTagFixed<uint32_t>(id_), wptr);
8038       uint32_t value32 = static_cast<uint32_t>(int_value_);
8039       memcpy(wptr, &value32, sizeof(value32));
8040       wptr += sizeof(uint32_t);
8041       break;
8042     }
8043     case static_cast<int>(pu::ProtoWireType::kFixed64): {
8044       wptr = pu::WriteVarInt(pu::MakeTagFixed<uint64_t>(id_), wptr);
8045       memcpy(wptr, &int_value_, sizeof(int_value_));
8046       wptr += sizeof(uint64_t);
8047       break;
8048     }
8049     case static_cast<int>(pu::ProtoWireType::kLengthDelimited): {
8050       ConstBytes payload = as_bytes();
8051       wptr = pu::WriteVarInt(pu::MakeTagLengthDelimited(id_), wptr);
8052       wptr = pu::WriteVarInt(payload.size, wptr);
8053       memcpy(wptr, payload.data, payload.size);
8054       wptr += payload.size;
8055       break;
8056     }
8057     default:
8058       PERFETTO_FATAL("Unknown field type %u", type_);
8059   }
8060   size_t written_size = static_cast<size_t>(wptr - start);
8061   PERFETTO_DCHECK(written_size > 0 && written_size < pu::kMaxMessageLength);
8062   PERFETTO_DCHECK(initial_size + written_size <= dst->size());
8063   dst->resize(initial_size + written_size);
8064 }
8065 
SerializeAndAppendTo(std::string * dst) const8066 void Field::SerializeAndAppendTo(std::string* dst) const {
8067   SerializeAndAppendToInternal(dst);
8068 }
8069 
SerializeAndAppendTo(std::vector<uint8_t> * dst) const8070 void Field::SerializeAndAppendTo(std::vector<uint8_t>* dst) const {
8071   SerializeAndAppendToInternal(dst);
8072 }
8073 
8074 }  // namespace protozero
8075 // gen_amalgamated begin source: src/protozero/message.cc
8076 /*
8077  * Copyright (C) 2017 The Android Open Source Project
8078  *
8079  * Licensed under the Apache License, Version 2.0 (the "License");
8080  * you may not use this file except in compliance with the License.
8081  * You may obtain a copy of the License at
8082  *
8083  *      http://www.apache.org/licenses/LICENSE-2.0
8084  *
8085  * Unless required by applicable law or agreed to in writing, software
8086  * distributed under the License is distributed on an "AS IS" BASIS,
8087  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8088  * See the License for the specific language governing permissions and
8089  * limitations under the License.
8090  */
8091 
8092 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
8093 
8094 #include <atomic>
8095 #include <type_traits>
8096 
8097 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
8098 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
8099 // gen_amalgamated expanded: #include "perfetto/protozero/message_arena.h"
8100 // gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
8101 
8102 #if !PERFETTO_IS_LITTLE_ENDIAN()
8103 // The memcpy() for float and double below needs to be adjusted if we want to
8104 // support big endian CPUs. There doesn't seem to be a compelling need today.
8105 #error Unimplemented for big endian archs.
8106 #endif
8107 
8108 namespace protozero {
8109 
8110 namespace {
8111 
8112 #if PERFETTO_DCHECK_IS_ON()
8113 std::atomic<uint32_t> g_generation;
8114 #endif
8115 
8116 }  // namespace
8117 
8118 // Do NOT put any code in the constructor or use default initialization.
8119 // Use the Reset() method below instead.
8120 
8121 // This method is called to initialize both root and nested messages.
Reset(ScatteredStreamWriter * stream_writer,MessageArena * arena)8122 void Message::Reset(ScatteredStreamWriter* stream_writer, MessageArena* arena) {
8123 // Older versions of libstdcxx don't have is_trivially_constructible.
8124 #if !defined(__GLIBCXX__) || __GLIBCXX__ >= 20170516
8125   static_assert(std::is_trivially_constructible<Message>::value,
8126                 "Message must be trivially constructible");
8127 #endif
8128 
8129   static_assert(std::is_trivially_destructible<Message>::value,
8130                 "Message must be trivially destructible");
8131   stream_writer_ = stream_writer;
8132   arena_ = arena;
8133   size_ = 0;
8134   size_field_ = nullptr;
8135   size_already_written_ = 0;
8136   nested_message_ = nullptr;
8137   finalized_ = false;
8138 #if PERFETTO_DCHECK_IS_ON()
8139   handle_ = nullptr;
8140   generation_ = g_generation.fetch_add(1, std::memory_order_relaxed);
8141 #endif
8142 }
8143 
AppendString(uint32_t field_id,const char * str)8144 void Message::AppendString(uint32_t field_id, const char* str) {
8145   AppendBytes(field_id, str, strlen(str));
8146 }
8147 
AppendBytes(uint32_t field_id,const void * src,size_t size)8148 void Message::AppendBytes(uint32_t field_id, const void* src, size_t size) {
8149   if (nested_message_)
8150     EndNestedMessage();
8151 
8152   PERFETTO_DCHECK(size < proto_utils::kMaxMessageLength);
8153   // Write the proto preamble (field id, type and length of the field).
8154   uint8_t buffer[proto_utils::kMaxSimpleFieldEncodedSize];
8155   uint8_t* pos = buffer;
8156   pos = proto_utils::WriteVarInt(proto_utils::MakeTagLengthDelimited(field_id),
8157                                  pos);
8158   pos = proto_utils::WriteVarInt(static_cast<uint32_t>(size), pos);
8159   WriteToStream(buffer, pos);
8160 
8161   const uint8_t* src_u8 = reinterpret_cast<const uint8_t*>(src);
8162   WriteToStream(src_u8, src_u8 + size);
8163 }
8164 
AppendScatteredBytes(uint32_t field_id,ContiguousMemoryRange * ranges,size_t num_ranges)8165 size_t Message::AppendScatteredBytes(uint32_t field_id,
8166                                      ContiguousMemoryRange* ranges,
8167                                      size_t num_ranges) {
8168   size_t size = 0;
8169   for (size_t i = 0; i < num_ranges; ++i) {
8170     size += ranges[i].size();
8171   }
8172 
8173   PERFETTO_DCHECK(size < proto_utils::kMaxMessageLength);
8174 
8175   uint8_t buffer[proto_utils::kMaxSimpleFieldEncodedSize];
8176   uint8_t* pos = buffer;
8177   pos = proto_utils::WriteVarInt(proto_utils::MakeTagLengthDelimited(field_id),
8178                                  pos);
8179   pos = proto_utils::WriteVarInt(static_cast<uint32_t>(size), pos);
8180   WriteToStream(buffer, pos);
8181 
8182   for (size_t i = 0; i < num_ranges; ++i) {
8183     auto& range = ranges[i];
8184     WriteToStream(range.begin, range.end);
8185   }
8186 
8187   return size;
8188 }
8189 
Finalize()8190 uint32_t Message::Finalize() {
8191   if (finalized_)
8192     return size_;
8193 
8194   if (nested_message_)
8195     EndNestedMessage();
8196 
8197   // Write the length of the nested message a posteriori, using a leading-zero
8198   // redundant varint encoding.
8199   if (size_field_) {
8200     PERFETTO_DCHECK(!finalized_);
8201     PERFETTO_DCHECK(size_ < proto_utils::kMaxMessageLength);
8202     PERFETTO_DCHECK(size_ >= size_already_written_);
8203     proto_utils::WriteRedundantVarInt(size_ - size_already_written_,
8204                                       size_field_);
8205     size_field_ = nullptr;
8206   }
8207 
8208   finalized_ = true;
8209 #if PERFETTO_DCHECK_IS_ON()
8210   if (handle_)
8211     handle_->reset_message();
8212 #endif
8213 
8214   return size_;
8215 }
8216 
BeginNestedMessageInternal(uint32_t field_id)8217 Message* Message::BeginNestedMessageInternal(uint32_t field_id) {
8218   if (nested_message_)
8219     EndNestedMessage();
8220 
8221   // Write the proto preamble for the nested message.
8222   uint8_t data[proto_utils::kMaxTagEncodedSize];
8223   uint8_t* data_end = proto_utils::WriteVarInt(
8224       proto_utils::MakeTagLengthDelimited(field_id), data);
8225   WriteToStream(data, data_end);
8226 
8227   Message* message = arena_->NewMessage();
8228   message->Reset(stream_writer_, arena_);
8229 
8230   // The length of the nested message cannot be known upfront. So right now
8231   // just reserve the bytes to encode the size after the nested message is done.
8232   message->set_size_field(
8233       stream_writer_->ReserveBytes(proto_utils::kMessageLengthFieldSize));
8234   size_ += proto_utils::kMessageLengthFieldSize;
8235 
8236   nested_message_ = message;
8237   return message;
8238 }
8239 
EndNestedMessage()8240 void Message::EndNestedMessage() {
8241   size_ += nested_message_->Finalize();
8242   arena_->DeleteLastMessage(nested_message_);
8243   nested_message_ = nullptr;
8244 }
8245 
8246 }  // namespace protozero
8247 // gen_amalgamated begin source: src/protozero/message_arena.cc
8248 /*
8249  * Copyright (C) 2020 The Android Open Source Project
8250  *
8251  * Licensed under the Apache License, Version 2.0 (the "License");
8252  * you may not use this file except in compliance with the License.
8253  * You may obtain a copy of the License at
8254  *
8255  *      http://www.apache.org/licenses/LICENSE-2.0
8256  *
8257  * Unless required by applicable law or agreed to in writing, software
8258  * distributed under the License is distributed on an "AS IS" BASIS,
8259  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8260  * See the License for the specific language governing permissions and
8261  * limitations under the License.
8262  */
8263 
8264 // gen_amalgamated expanded: #include "perfetto/protozero/message_arena.h"
8265 
8266 #include <atomic>
8267 #include <type_traits>
8268 
8269 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
8270 // gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
8271 
8272 namespace protozero {
8273 
MessageArena()8274 MessageArena::MessageArena() {
8275   // The code below assumes that there is always at least one block.
8276   blocks_.emplace_front();
8277   static_assert(std::alignment_of<decltype(blocks_.back().storage[0])>::value >=
8278                     alignof(Message),
8279                 "MessageArea's storage is not properly aligned");
8280 }
8281 
8282 MessageArena::~MessageArena() = default;
8283 
NewMessage()8284 Message* MessageArena::NewMessage() {
8285   PERFETTO_DCHECK(!blocks_.empty());  // Should never become empty.
8286 
8287   Block* block = &blocks_.back();
8288   if (PERFETTO_UNLIKELY(block->entries >= Block::kCapacity)) {
8289     blocks_.emplace_back();
8290     block = &blocks_.back();
8291   }
8292   const auto idx = block->entries++;
8293   void* storage = &block->storage[idx];
8294   PERFETTO_ASAN_UNPOISON(storage, sizeof(Message));
8295   return new (storage) Message();
8296 }
8297 
DeleteLastMessageInternal()8298 void MessageArena::DeleteLastMessageInternal() {
8299   PERFETTO_DCHECK(!blocks_.empty());  // Should never be empty, see below.
8300   Block* block = &blocks_.back();
8301   PERFETTO_DCHECK(block->entries > 0);
8302 
8303   // This is the reason why there is no ~Message() call here.
8304   // MessageArea::Reset() (see header) also relies on dtor being trivial.
8305   static_assert(std::is_trivially_destructible<Message>::value,
8306                 "Message must be trivially destructible");
8307 
8308   --block->entries;
8309   PERFETTO_ASAN_POISON(&block->storage[block->entries], sizeof(Message));
8310 
8311   // Don't remove the first block to avoid malloc/free calls when the root
8312   // message is reset. Hitting the allocator all the times is a waste of time.
8313   if (block->entries == 0 && blocks_.size() > 1) {
8314     blocks_.pop_back();
8315   }
8316 }
8317 
8318 }  // namespace protozero
8319 // gen_amalgamated begin source: src/protozero/message_handle.cc
8320 /*
8321  * Copyright (C) 2017 The Android Open Source Project
8322  *
8323  * Licensed under the Apache License, Version 2.0 (the "License");
8324  * you may not use this file except in compliance with the License.
8325  * You may obtain a copy of the License at
8326  *
8327  *      http://www.apache.org/licenses/LICENSE-2.0
8328  *
8329  * Unless required by applicable law or agreed to in writing, software
8330  * distributed under the License is distributed on an "AS IS" BASIS,
8331  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8332  * See the License for the specific language governing permissions and
8333  * limitations under the License.
8334  */
8335 
8336 // gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
8337 
8338 #include <utility>
8339 
8340 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
8341 
8342 namespace protozero {
8343 
MessageHandleBase(Message * message)8344 MessageHandleBase::MessageHandleBase(Message* message) : message_(message) {
8345 #if PERFETTO_DCHECK_IS_ON()
8346   generation_ = message_ ? message->generation_ : 0;
8347   if (message_)
8348     message_->set_handle(this);
8349 #endif
8350 }
8351 
~MessageHandleBase()8352 MessageHandleBase::~MessageHandleBase() {
8353   if (message_) {
8354 #if PERFETTO_DCHECK_IS_ON()
8355     PERFETTO_DCHECK(generation_ == message_->generation_);
8356 #endif
8357     FinalizeMessage();
8358   }
8359 }
8360 
MessageHandleBase(MessageHandleBase && other)8361 MessageHandleBase::MessageHandleBase(MessageHandleBase&& other) noexcept {
8362   Move(std::move(other));
8363 }
8364 
operator =(MessageHandleBase && other)8365 MessageHandleBase& MessageHandleBase::operator=(MessageHandleBase&& other) {
8366   // If the current handle was pointing to a message and is being reset to a new
8367   // one, finalize the old message. However, if the other message is the same as
8368   // the one we point to, don't finalize.
8369   if (message_ && message_ != other.message_)
8370     FinalizeMessage();
8371   Move(std::move(other));
8372   return *this;
8373 }
8374 
Move(MessageHandleBase && other)8375 void MessageHandleBase::Move(MessageHandleBase&& other) {
8376   message_ = other.message_;
8377   other.message_ = nullptr;
8378 #if PERFETTO_DCHECK_IS_ON()
8379   if (message_) {
8380     generation_ = message_->generation_;
8381     message_->set_handle(this);
8382   }
8383 #endif
8384 }
8385 
8386 }  // namespace protozero
8387 // gen_amalgamated begin source: src/protozero/packed_repeated_fields.cc
8388 /*
8389  * Copyright (C) 2017 The Android Open Source Project
8390  *
8391  * Licensed under the Apache License, Version 2.0 (the "License");
8392  * you may not use this file except in compliance with the License.
8393  * You may obtain a copy of the License at
8394  *
8395  *      http://www.apache.org/licenses/LICENSE-2.0
8396  *
8397  * Unless required by applicable law or agreed to in writing, software
8398  * distributed under the License is distributed on an "AS IS" BASIS,
8399  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8400  * See the License for the specific language governing permissions and
8401  * limitations under the License.
8402  */
8403 
8404 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
8405 
8406 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
8407 
8408 namespace protozero {
8409 
8410 // static
8411 constexpr size_t PackedBufferBase::kOnStackStorageSize;
8412 
GrowSlowpath()8413 void PackedBufferBase::GrowSlowpath() {
8414   size_t write_off = static_cast<size_t>(write_ptr_ - storage_begin_);
8415   size_t old_size = static_cast<size_t>(storage_end_ - storage_begin_);
8416   size_t new_size = old_size < 65536 ? (old_size * 2) : (old_size * 3 / 2);
8417   new_size = perfetto::base::AlignUp<4096>(new_size);
8418   std::unique_ptr<uint8_t[]> new_buf(new uint8_t[new_size]);
8419   memcpy(new_buf.get(), storage_begin_, old_size);
8420   heap_buf_ = std::move(new_buf);
8421   storage_begin_ = heap_buf_.get();
8422   storage_end_ = storage_begin_ + new_size;
8423   write_ptr_ = storage_begin_ + write_off;
8424 }
8425 
Reset()8426 void PackedBufferBase::Reset() {
8427   heap_buf_.reset();
8428   storage_begin_ = reinterpret_cast<uint8_t*>(&stack_buf_[0]);
8429   storage_end_ = reinterpret_cast<uint8_t*>(&stack_buf_[kOnStackStorageSize]);
8430   write_ptr_ = storage_begin_;
8431 }
8432 
8433 }  // namespace protozero
8434 // gen_amalgamated begin source: src/protozero/proto_decoder.cc
8435 /*
8436  * Copyright (C) 2018 The Android Open Source Project
8437  *
8438  * Licensed under the Apache License, Version 2.0 (the "License");
8439  * you may not use this file except in compliance with the License.
8440  * You may obtain a copy of the License at
8441  *
8442  *      http://www.apache.org/licenses/LICENSE-2.0
8443  *
8444  * Unless required by applicable law or agreed to in writing, software
8445  * distributed under the License is distributed on an "AS IS" BASIS,
8446  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8447  * See the License for the specific language governing permissions and
8448  * limitations under the License.
8449  */
8450 
8451 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
8452 
8453 #include <string.h>
8454 #include <limits>
8455 
8456 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
8457 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
8458 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
8459 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
8460 
8461 namespace protozero {
8462 
8463 using namespace proto_utils;
8464 
8465 #if !PERFETTO_IS_LITTLE_ENDIAN()
8466 #error Unimplemented for big endian archs.
8467 #endif
8468 
8469 namespace {
8470 
8471 struct ParseFieldResult {
8472   enum ParseResult { kAbort, kSkip, kOk };
8473   ParseResult parse_res;
8474   const uint8_t* next;
8475   Field field;
8476 };
8477 
8478 // Parses one field and returns the field itself and a pointer to the next
8479 // field to parse. If parsing fails, the returned |next| == |buffer|.
8480 PERFETTO_ALWAYS_INLINE ParseFieldResult
ParseOneField(const uint8_t * const buffer,const uint8_t * const end)8481 ParseOneField(const uint8_t* const buffer, const uint8_t* const end) {
8482   ParseFieldResult res{ParseFieldResult::kAbort, buffer, Field{}};
8483 
8484   // The first byte of a proto field is structured as follows:
8485   // The least 3 significant bits determine the field type.
8486   // The most 5 significant bits determine the field id. If MSB == 1, the
8487   // field id continues on the next bytes following the VarInt encoding.
8488   const uint8_t kFieldTypeNumBits = 3;
8489   const uint64_t kFieldTypeMask = (1 << kFieldTypeNumBits) - 1;  // 0000 0111;
8490   const uint8_t* pos = buffer;
8491 
8492   // If we've already hit the end, just return an invalid field.
8493   if (PERFETTO_UNLIKELY(pos >= end))
8494     return res;
8495 
8496   uint64_t preamble = 0;
8497   if (PERFETTO_LIKELY(*pos < 0x80)) {  // Fastpath for fields with ID < 16.
8498     preamble = *(pos++);
8499   } else {
8500     const uint8_t* next = ParseVarInt(pos, end, &preamble);
8501     if (PERFETTO_UNLIKELY(pos == next))
8502       return res;
8503     pos = next;
8504   }
8505 
8506   uint32_t field_id = static_cast<uint32_t>(preamble >> kFieldTypeNumBits);
8507   if (field_id == 0 || pos >= end)
8508     return res;
8509 
8510   auto field_type = static_cast<uint8_t>(preamble & kFieldTypeMask);
8511   const uint8_t* new_pos = pos;
8512   uint64_t int_value = 0;
8513   uint64_t size = 0;
8514 
8515   switch (field_type) {
8516     case static_cast<uint8_t>(ProtoWireType::kVarInt): {
8517       new_pos = ParseVarInt(pos, end, &int_value);
8518 
8519       // new_pos not being greater than pos means ParseVarInt could not fully
8520       // parse the number. This is because we are out of space in the buffer.
8521       // Set the id to zero and return but don't update the offset so a future
8522       // read can read this field.
8523       if (PERFETTO_UNLIKELY(new_pos == pos))
8524         return res;
8525 
8526       break;
8527     }
8528 
8529     case static_cast<uint8_t>(ProtoWireType::kLengthDelimited): {
8530       uint64_t payload_length;
8531       new_pos = ParseVarInt(pos, end, &payload_length);
8532       if (PERFETTO_UNLIKELY(new_pos == pos))
8533         return res;
8534 
8535       // ParseVarInt guarantees that |new_pos| <= |end| when it succeeds;
8536       if (payload_length > static_cast<uint64_t>(end - new_pos))
8537         return res;
8538 
8539       const uintptr_t payload_start = reinterpret_cast<uintptr_t>(new_pos);
8540       int_value = payload_start;
8541       size = payload_length;
8542       new_pos += payload_length;
8543       break;
8544     }
8545 
8546     case static_cast<uint8_t>(ProtoWireType::kFixed64): {
8547       new_pos = pos + sizeof(uint64_t);
8548       if (PERFETTO_UNLIKELY(new_pos > end))
8549         return res;
8550       memcpy(&int_value, pos, sizeof(uint64_t));
8551       break;
8552     }
8553 
8554     case static_cast<uint8_t>(ProtoWireType::kFixed32): {
8555       new_pos = pos + sizeof(uint32_t);
8556       if (PERFETTO_UNLIKELY(new_pos > end))
8557         return res;
8558       memcpy(&int_value, pos, sizeof(uint32_t));
8559       break;
8560     }
8561 
8562     default:
8563       PERFETTO_DLOG("Invalid proto field type: %u", field_type);
8564       return res;
8565   }
8566 
8567   res.next = new_pos;
8568 
8569   if (PERFETTO_UNLIKELY(field_id > std::numeric_limits<uint16_t>::max())) {
8570     PERFETTO_DLOG("Skipping field %" PRIu32 " because its id > 0xFFFF",
8571                   field_id);
8572     res.parse_res = ParseFieldResult::kSkip;
8573     return res;
8574   }
8575 
8576   if (PERFETTO_UNLIKELY(size > proto_utils::kMaxMessageLength)) {
8577     PERFETTO_DLOG("Skipping field %" PRIu32 " because it's too big (%" PRIu64
8578                   " KB)",
8579                   field_id, size / 1024);
8580     res.parse_res = ParseFieldResult::kSkip;
8581     return res;
8582   }
8583 
8584   res.parse_res = ParseFieldResult::kOk;
8585   res.field.initialize(static_cast<uint16_t>(field_id), field_type, int_value,
8586                        static_cast<uint32_t>(size));
8587   return res;
8588 }
8589 
8590 }  // namespace
8591 
FindField(uint32_t field_id)8592 Field ProtoDecoder::FindField(uint32_t field_id) {
8593   Field res{};
8594   auto old_position = read_ptr_;
8595   read_ptr_ = begin_;
8596   for (auto f = ReadField(); f.valid(); f = ReadField()) {
8597     if (f.id() == field_id) {
8598       res = f;
8599       break;
8600     }
8601   }
8602   read_ptr_ = old_position;
8603   return res;
8604 }
8605 
8606 PERFETTO_ALWAYS_INLINE
ReadField()8607 Field ProtoDecoder::ReadField() {
8608   ParseFieldResult res;
8609   do {
8610     res = ParseOneField(read_ptr_, end_);
8611     read_ptr_ = res.next;
8612   } while (PERFETTO_UNLIKELY(res.parse_res == ParseFieldResult::kSkip));
8613   return res.field;
8614 }
8615 
ParseAllFields()8616 void TypedProtoDecoderBase::ParseAllFields() {
8617   const uint8_t* cur = begin_;
8618   ParseFieldResult res;
8619   for (;;) {
8620     res = ParseOneField(cur, end_);
8621     PERFETTO_DCHECK(res.parse_res != ParseFieldResult::kOk || res.next != cur);
8622     cur = res.next;
8623     if (PERFETTO_UNLIKELY(res.parse_res == ParseFieldResult::kSkip)) {
8624       continue;
8625     } else if (PERFETTO_UNLIKELY(res.parse_res == ParseFieldResult::kAbort)) {
8626       break;
8627     }
8628     PERFETTO_DCHECK(res.parse_res == ParseFieldResult::kOk);
8629     PERFETTO_DCHECK(res.field.valid());
8630     auto field_id = res.field.id();
8631     if (PERFETTO_UNLIKELY(field_id >= num_fields_))
8632       continue;
8633 
8634     Field* fld = &fields_[field_id];
8635     if (PERFETTO_LIKELY(!fld->valid())) {
8636       // This is the first time we see this field.
8637       *fld = std::move(res.field);
8638     } else {
8639       // Repeated field case.
8640       // In this case we need to:
8641       // 1. Append the last value of the field to end of the repeated field
8642       //    storage.
8643       // 2. Replace the default instance at offset |field_id| with the current
8644       //    value. This is because in case of repeated field a call to Get(X) is
8645       //    supposed to return the last value of X, not the first one.
8646       // This is so that the RepeatedFieldIterator will iterate in the right
8647       // order, see comments on RepeatedFieldIterator.
8648       if (PERFETTO_UNLIKELY(size_ >= capacity_)) {
8649         ExpandHeapStorage();
8650         // ExpandHeapStorage moves fields_ so we need to update the ptr to fld:
8651         fld = &fields_[field_id];
8652         PERFETTO_DCHECK(size_ < capacity_);
8653       }
8654       fields_[size_++] = *fld;
8655       *fld = std::move(res.field);
8656     }
8657   }
8658   read_ptr_ = res.next;
8659 }
8660 
ExpandHeapStorage()8661 void TypedProtoDecoderBase::ExpandHeapStorage() {
8662   uint32_t new_capacity = capacity_ * 2;
8663   PERFETTO_CHECK(new_capacity > size_);
8664   std::unique_ptr<Field[]> new_storage(new Field[new_capacity]);
8665 
8666   static_assert(std::is_trivially_copyable<Field>::value,
8667                 "Field must be trivially copyable");
8668   memcpy(&new_storage[0], fields_, sizeof(Field) * size_);
8669 
8670   heap_storage_ = std::move(new_storage);
8671   fields_ = &heap_storage_[0];
8672   capacity_ = new_capacity;
8673 }
8674 
8675 }  // namespace protozero
8676 // gen_amalgamated begin source: src/protozero/scattered_heap_buffer.cc
8677 /*
8678  * Copyright (C) 2017 The Android Open Source Project
8679  *
8680  * Licensed under the Apache License, Version 2.0 (the "License");
8681  * you may not use this file except in compliance with the License.
8682  * You may obtain a copy of the License at
8683  *
8684  *      http://www.apache.org/licenses/LICENSE-2.0
8685  *
8686  * Unless required by applicable law or agreed to in writing, software
8687  * distributed under the License is distributed on an "AS IS" BASIS,
8688  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8689  * See the License for the specific language governing permissions and
8690  * limitations under the License.
8691  */
8692 
8693 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
8694 
8695 #include <algorithm>
8696 
8697 namespace protozero {
8698 
Slice()8699 ScatteredHeapBuffer::Slice::Slice()
8700     : buffer_(nullptr), size_(0u), unused_bytes_(0u) {}
8701 
Slice(size_t size)8702 ScatteredHeapBuffer::Slice::Slice(size_t size)
8703     : buffer_(std::unique_ptr<uint8_t[]>(new uint8_t[size])),
8704       size_(size),
8705       unused_bytes_(size) {
8706   PERFETTO_DCHECK(size);
8707   Clear();
8708 }
8709 
8710 ScatteredHeapBuffer::Slice::Slice(Slice&& slice) noexcept = default;
8711 
8712 ScatteredHeapBuffer::Slice::~Slice() = default;
8713 
8714 ScatteredHeapBuffer::Slice& ScatteredHeapBuffer::Slice::operator=(Slice&&) =
8715     default;
8716 
Clear()8717 void ScatteredHeapBuffer::Slice::Clear() {
8718   unused_bytes_ = size_;
8719 #if PERFETTO_DCHECK_IS_ON()
8720   memset(start(), 0xff, size_);
8721 #endif  // PERFETTO_DCHECK_IS_ON()
8722 }
8723 
ScatteredHeapBuffer(size_t initial_slice_size_bytes,size_t maximum_slice_size_bytes)8724 ScatteredHeapBuffer::ScatteredHeapBuffer(size_t initial_slice_size_bytes,
8725                                          size_t maximum_slice_size_bytes)
8726     : next_slice_size_(initial_slice_size_bytes),
8727       maximum_slice_size_(maximum_slice_size_bytes) {
8728   PERFETTO_DCHECK(next_slice_size_ && maximum_slice_size_);
8729   PERFETTO_DCHECK(maximum_slice_size_ >= initial_slice_size_bytes);
8730 }
8731 
8732 ScatteredHeapBuffer::~ScatteredHeapBuffer() = default;
8733 
GetNewBuffer()8734 protozero::ContiguousMemoryRange ScatteredHeapBuffer::GetNewBuffer() {
8735   PERFETTO_CHECK(writer_);
8736   AdjustUsedSizeOfCurrentSlice();
8737 
8738   if (cached_slice_.start()) {
8739     slices_.push_back(std::move(cached_slice_));
8740     PERFETTO_DCHECK(!cached_slice_.start());
8741   } else {
8742     slices_.emplace_back(next_slice_size_);
8743   }
8744   next_slice_size_ = std::min(maximum_slice_size_, next_slice_size_ * 2);
8745   return slices_.back().GetTotalRange();
8746 }
8747 
8748 const std::vector<ScatteredHeapBuffer::Slice>&
GetSlices()8749 ScatteredHeapBuffer::GetSlices() {
8750   AdjustUsedSizeOfCurrentSlice();
8751   return slices_;
8752 }
8753 
StitchSlices()8754 std::vector<uint8_t> ScatteredHeapBuffer::StitchSlices() {
8755   size_t stitched_size = 0u;
8756   const auto& slices = GetSlices();
8757   for (const auto& slice : slices)
8758     stitched_size += slice.size() - slice.unused_bytes();
8759 
8760   std::vector<uint8_t> buffer;
8761   buffer.reserve(stitched_size);
8762   for (const auto& slice : slices) {
8763     auto used_range = slice.GetUsedRange();
8764     buffer.insert(buffer.end(), used_range.begin, used_range.end);
8765   }
8766   return buffer;
8767 }
8768 
GetRanges()8769 std::vector<protozero::ContiguousMemoryRange> ScatteredHeapBuffer::GetRanges() {
8770   std::vector<protozero::ContiguousMemoryRange> ranges;
8771   for (const auto& slice : GetSlices())
8772     ranges.push_back(slice.GetUsedRange());
8773   return ranges;
8774 }
8775 
AdjustUsedSizeOfCurrentSlice()8776 void ScatteredHeapBuffer::AdjustUsedSizeOfCurrentSlice() {
8777   if (!slices_.empty())
8778     slices_.back().set_unused_bytes(writer_->bytes_available());
8779 }
8780 
GetTotalSize()8781 size_t ScatteredHeapBuffer::GetTotalSize() {
8782   size_t total_size = 0;
8783   for (auto& slice : slices_) {
8784     total_size += slice.size();
8785   }
8786   return total_size;
8787 }
8788 
Reset()8789 void ScatteredHeapBuffer::Reset() {
8790   if (slices_.empty())
8791     return;
8792   cached_slice_ = std::move(slices_.front());
8793   cached_slice_.Clear();
8794   slices_.clear();
8795 }
8796 
8797 }  // namespace protozero
8798 // gen_amalgamated begin source: src/protozero/scattered_stream_null_delegate.cc
8799 // gen_amalgamated begin header: include/perfetto/protozero/scattered_stream_null_delegate.h
8800 /*
8801  * Copyright (C) 2018 The Android Open Source Project
8802  *
8803  * Licensed under the Apache License, Version 2.0 (the "License");
8804  * you may not use this file except in compliance with the License.
8805  * You may obtain a copy of the License at
8806  *
8807  *      http://www.apache.org/licenses/LICENSE-2.0
8808  *
8809  * Unless required by applicable law or agreed to in writing, software
8810  * distributed under the License is distributed on an "AS IS" BASIS,
8811  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8812  * See the License for the specific language governing permissions and
8813  * limitations under the License.
8814  */
8815 
8816 #ifndef INCLUDE_PERFETTO_PROTOZERO_SCATTERED_STREAM_NULL_DELEGATE_H_
8817 #define INCLUDE_PERFETTO_PROTOZERO_SCATTERED_STREAM_NULL_DELEGATE_H_
8818 
8819 #include <memory>
8820 #include <vector>
8821 
8822 // gen_amalgamated expanded: #include "perfetto/base/export.h"
8823 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
8824 // gen_amalgamated expanded: #include "perfetto/protozero/contiguous_memory_range.h"
8825 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
8826 
8827 namespace protozero {
8828 
8829 class PERFETTO_EXPORT ScatteredStreamWriterNullDelegate
8830     : public ScatteredStreamWriter::Delegate {
8831  public:
8832   explicit ScatteredStreamWriterNullDelegate(size_t chunk_size);
8833   ~ScatteredStreamWriterNullDelegate() override;
8834 
8835   // protozero::ScatteredStreamWriter::Delegate implementation.
8836   ContiguousMemoryRange GetNewBuffer() override;
8837 
8838  private:
8839   const size_t chunk_size_;
8840   std::unique_ptr<uint8_t[]> chunk_;
8841 };
8842 
8843 }  // namespace protozero
8844 
8845 #endif  // INCLUDE_PERFETTO_PROTOZERO_SCATTERED_STREAM_NULL_DELEGATE_H_
8846 /*
8847  * Copyright (C) 2018 The Android Open Source Project
8848  *
8849  * Licensed under the Apache License, Version 2.0 (the "License");
8850  * you may not use this file except in compliance with the License.
8851  * You may obtain a copy of the License at
8852  *
8853  *      http://www.apache.org/licenses/LICENSE-2.0
8854  *
8855  * Unless required by applicable law or agreed to in writing, software
8856  * distributed under the License is distributed on an "AS IS" BASIS,
8857  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8858  * See the License for the specific language governing permissions and
8859  * limitations under the License.
8860  */
8861 
8862 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_null_delegate.h"
8863 
8864 namespace protozero {
8865 
8866 // An implementation of ScatteredStreamWriter::Delegate which always returns
8867 // the same piece of memory.
8868 // This is used when we need to no-op the writers (e.g. during teardown or in
8869 // case of resource exhaustion), avoiding that the clients have to deal with
8870 // nullptr checks.
ScatteredStreamWriterNullDelegate(size_t chunk_size)8871 ScatteredStreamWriterNullDelegate::ScatteredStreamWriterNullDelegate(
8872     size_t chunk_size)
8873     : chunk_size_(chunk_size),
8874       chunk_(std::unique_ptr<uint8_t[]>(new uint8_t[chunk_size_])) {}
8875 
~ScatteredStreamWriterNullDelegate()8876 ScatteredStreamWriterNullDelegate::~ScatteredStreamWriterNullDelegate() {}
8877 
GetNewBuffer()8878 ContiguousMemoryRange ScatteredStreamWriterNullDelegate::GetNewBuffer() {
8879   return {chunk_.get(), chunk_.get() + chunk_size_};
8880 }
8881 
8882 }  // namespace protozero
8883 // gen_amalgamated begin source: src/protozero/scattered_stream_writer.cc
8884 /*
8885  * Copyright (C) 2017 The Android Open Source Project
8886  *
8887  * Licensed under the Apache License, Version 2.0 (the "License");
8888  * you may not use this file except in compliance with the License.
8889  * You may obtain a copy of the License at
8890  *
8891  *      http://www.apache.org/licenses/LICENSE-2.0
8892  *
8893  * Unless required by applicable law or agreed to in writing, software
8894  * distributed under the License is distributed on an "AS IS" BASIS,
8895  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8896  * See the License for the specific language governing permissions and
8897  * limitations under the License.
8898  */
8899 
8900 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
8901 
8902 #include <algorithm>
8903 
8904 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
8905 
8906 namespace protozero {
8907 
~Delegate()8908 ScatteredStreamWriter::Delegate::~Delegate() {}
8909 
ScatteredStreamWriter(Delegate * delegate)8910 ScatteredStreamWriter::ScatteredStreamWriter(Delegate* delegate)
8911     : delegate_(delegate),
8912       cur_range_({nullptr, nullptr}),
8913       write_ptr_(nullptr) {}
8914 
~ScatteredStreamWriter()8915 ScatteredStreamWriter::~ScatteredStreamWriter() {}
8916 
Reset(ContiguousMemoryRange range)8917 void ScatteredStreamWriter::Reset(ContiguousMemoryRange range) {
8918   written_previously_ += static_cast<uint64_t>(write_ptr_ - cur_range_.begin);
8919   cur_range_ = range;
8920   write_ptr_ = range.begin;
8921   PERFETTO_DCHECK(!write_ptr_ || write_ptr_ < cur_range_.end);
8922 }
8923 
Extend()8924 void ScatteredStreamWriter::Extend() {
8925   Reset(delegate_->GetNewBuffer());
8926 }
8927 
WriteBytesSlowPath(const uint8_t * src,size_t size)8928 void ScatteredStreamWriter::WriteBytesSlowPath(const uint8_t* src,
8929                                                size_t size) {
8930   size_t bytes_left = size;
8931   while (bytes_left > 0) {
8932     if (write_ptr_ >= cur_range_.end)
8933       Extend();
8934     const size_t burst_size = std::min(bytes_available(), bytes_left);
8935     WriteBytesUnsafe(src, burst_size);
8936     bytes_left -= burst_size;
8937     src += burst_size;
8938   }
8939 }
8940 
8941 // TODO(primiano): perf optimization: I suspect that at the end this will always
8942 // be called with |size| == 4, in which case we might just hardcode it.
ReserveBytes(size_t size)8943 uint8_t* ScatteredStreamWriter::ReserveBytes(size_t size) {
8944   if (write_ptr_ + size > cur_range_.end) {
8945     // Assume the reservations are always < Delegate::GetNewBuffer().size(),
8946     // so that one single call to Extend() will definitely give enough headroom.
8947     Extend();
8948     PERFETTO_DCHECK(write_ptr_ + size <= cur_range_.end);
8949   }
8950   uint8_t* begin = write_ptr_;
8951   write_ptr_ += size;
8952 #if PERFETTO_DCHECK_IS_ON()
8953   memset(begin, 0, size);
8954 #endif
8955   return begin;
8956 }
8957 
8958 }  // namespace protozero
8959 // gen_amalgamated begin source: src/protozero/static_buffer.cc
8960 // gen_amalgamated begin header: include/perfetto/protozero/static_buffer.h
8961 /*
8962  * Copyright (C) 2019 The Android Open Source Project
8963  *
8964  * Licensed under the Apache License, Version 2.0 (the "License");
8965  * you may not use this file except in compliance with the License.
8966  * You may obtain a copy of the License at
8967  *
8968  *      http://www.apache.org/licenses/LICENSE-2.0
8969  *
8970  * Unless required by applicable law or agreed to in writing, software
8971  * distributed under the License is distributed on an "AS IS" BASIS,
8972  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8973  * See the License for the specific language governing permissions and
8974  * limitations under the License.
8975  */
8976 
8977 #ifndef INCLUDE_PERFETTO_PROTOZERO_STATIC_BUFFER_H_
8978 #define INCLUDE_PERFETTO_PROTOZERO_STATIC_BUFFER_H_
8979 
8980 #include <memory>
8981 #include <string>
8982 #include <vector>
8983 
8984 // gen_amalgamated expanded: #include "perfetto/base/export.h"
8985 // gen_amalgamated expanded: #include "perfetto/protozero/root_message.h"
8986 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
8987 
8988 namespace protozero {
8989 
8990 class Message;
8991 
8992 // A simple implementation of ScatteredStreamWriter::Delegate backed by a
8993 // fixed-size buffer. It doesn't support expansion. The caller needs to ensure
8994 // to never write more than the size of the buffer. Will CHECK() otherwise.
8995 class PERFETTO_EXPORT StaticBufferDelegate
8996     : public ScatteredStreamWriter::Delegate {
8997  public:
StaticBufferDelegate(uint8_t * buf,size_t len)8998   StaticBufferDelegate(uint8_t* buf, size_t len) : range_{buf, buf + len} {}
8999   ~StaticBufferDelegate() override;
9000 
9001   // ScatteredStreamWriter::Delegate implementation.
9002   ContiguousMemoryRange GetNewBuffer() override;
9003 
9004   ContiguousMemoryRange const range_;
9005   bool get_new_buffer_called_once_ = false;
9006 };
9007 
9008 // Helper function to create protozero messages backed by a fixed-size buffer
9009 // in one line. You can write:
9010 //   protozero::Static<protozero::MyMessage> msg(buf.data(), buf.size());
9011 //   msg->set_stuff(...);
9012 //   size_t bytes_encoded = msg.Finalize();
9013 template <typename T /* protozero::Message */>
9014 class StaticBuffered {
9015  public:
StaticBuffered(void * buf,size_t len)9016   StaticBuffered(void* buf, size_t len)
9017       : delegate_(reinterpret_cast<uint8_t*>(buf), len), writer_(&delegate_) {
9018     msg_.Reset(&writer_);
9019   }
9020 
9021   // This can't be neither copied nor moved because Message hands out pointers
9022   // to itself when creating submessages.
9023   StaticBuffered(const StaticBuffered&) = delete;
9024   StaticBuffered& operator=(const StaticBuffered&) = delete;
9025   StaticBuffered(StaticBuffered&&) = delete;
9026   StaticBuffered& operator=(StaticBuffered&&) = delete;
9027 
get()9028   T* get() { return &msg_; }
operator ->()9029   T* operator->() { return &msg_; }
9030 
9031   // The lack of a size() method is deliberate. It's to prevent that one
9032   // accidentally calls size() before Finalize().
9033 
9034   // Returns the number of encoded bytes (<= the size passed in the ctor).
Finalize()9035   size_t Finalize() {
9036     msg_.Finalize();
9037     return static_cast<size_t>(writer_.write_ptr() - delegate_.range_.begin);
9038   }
9039 
9040  private:
9041   StaticBufferDelegate delegate_;
9042   ScatteredStreamWriter writer_;
9043   RootMessage<T> msg_;
9044 };
9045 
9046 // Helper function to create stack-based protozero messages in one line.
9047 // You can write:
9048 //   protozero::StackBuffered<protozero::MyMessage, 16> msg;
9049 //   msg->set_stuff(...);
9050 //   size_t bytes_encoded = msg.Finalize();
9051 template <typename T /* protozero::Message */, size_t N>
9052 class StackBuffered : public StaticBuffered<T> {
9053  public:
StackBuffered()9054   StackBuffered() : StaticBuffered<T>(&buf_[0], N) {}
9055 
9056  private:
9057   uint8_t buf_[N];  // Deliberately not initialized.
9058 };
9059 
9060 }  // namespace protozero
9061 
9062 #endif  // INCLUDE_PERFETTO_PROTOZERO_STATIC_BUFFER_H_
9063 /*
9064  * Copyright (C) 2019 The Android Open Source Project
9065  *
9066  * Licensed under the Apache License, Version 2.0 (the "License");
9067  * you may not use this file except in compliance with the License.
9068  * You may obtain a copy of the License at
9069  *
9070  *      http://www.apache.org/licenses/LICENSE-2.0
9071  *
9072  * Unless required by applicable law or agreed to in writing, software
9073  * distributed under the License is distributed on an "AS IS" BASIS,
9074  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9075  * See the License for the specific language governing permissions and
9076  * limitations under the License.
9077  */
9078 
9079 // gen_amalgamated expanded: #include "perfetto/protozero/static_buffer.h"
9080 
9081 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
9082 
9083 namespace protozero {
9084 
9085 StaticBufferDelegate::~StaticBufferDelegate() = default;
9086 
GetNewBuffer()9087 ContiguousMemoryRange StaticBufferDelegate::GetNewBuffer() {
9088   if (get_new_buffer_called_once_) {
9089     // This is the 2nd time GetNewBuffer is called. The estimate is wrong. We
9090     // shouldn't try to grow the buffer after the initial call.
9091     PERFETTO_FATAL("Static buffer too small");
9092   }
9093   get_new_buffer_called_once_ = true;
9094   return range_;
9095 }
9096 
9097 }  // namespace protozero
9098 // gen_amalgamated begin source: src/protozero/virtual_destructors.cc
9099 /*
9100  * Copyright (C) 2019 The Android Open Source Project
9101  *
9102  * Licensed under the Apache License, Version 2.0 (the "License");
9103  * you may not use this file except in compliance with the License.
9104  * You may obtain a copy of the License at
9105  *
9106  *      http://www.apache.org/licenses/LICENSE-2.0
9107  *
9108  * Unless required by applicable law or agreed to in writing, software
9109  * distributed under the License is distributed on an "AS IS" BASIS,
9110  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9111  * See the License for the specific language governing permissions and
9112  * limitations under the License.
9113  */
9114 
9115 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
9116 
9117 namespace protozero {
9118 
9119 CppMessageObj::~CppMessageObj() = default;
9120 
9121 }  // namespace protozero
9122 // gen_amalgamated begin source: gen/protos/perfetto/common/android_energy_consumer_descriptor.gen.cc
9123 // gen_amalgamated begin header: gen/protos/perfetto/common/android_energy_consumer_descriptor.gen.h
9124 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
9125 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_ENERGY_CONSUMER_DESCRIPTOR_PROTO_CPP_H_
9126 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_ENERGY_CONSUMER_DESCRIPTOR_PROTO_CPP_H_
9127 
9128 #include <stdint.h>
9129 #include <bitset>
9130 #include <vector>
9131 #include <string>
9132 #include <type_traits>
9133 
9134 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
9135 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
9136 // gen_amalgamated expanded: #include "perfetto/base/export.h"
9137 
9138 namespace perfetto {
9139 namespace protos {
9140 namespace gen {
9141 class AndroidEnergyConsumerDescriptor;
9142 class AndroidEnergyConsumer;
9143 }  // namespace perfetto
9144 }  // namespace protos
9145 }  // namespace gen
9146 
9147 namespace protozero {
9148 class Message;
9149 }  // namespace protozero
9150 
9151 namespace perfetto {
9152 namespace protos {
9153 namespace gen {
9154 
9155 class PERFETTO_EXPORT AndroidEnergyConsumerDescriptor : public ::protozero::CppMessageObj {
9156  public:
9157   enum FieldNumbers {
9158     kEnergyConsumersFieldNumber = 1,
9159   };
9160 
9161   AndroidEnergyConsumerDescriptor();
9162   ~AndroidEnergyConsumerDescriptor() override;
9163   AndroidEnergyConsumerDescriptor(AndroidEnergyConsumerDescriptor&&) noexcept;
9164   AndroidEnergyConsumerDescriptor& operator=(AndroidEnergyConsumerDescriptor&&);
9165   AndroidEnergyConsumerDescriptor(const AndroidEnergyConsumerDescriptor&);
9166   AndroidEnergyConsumerDescriptor& operator=(const AndroidEnergyConsumerDescriptor&);
9167   bool operator==(const AndroidEnergyConsumerDescriptor&) const;
operator !=(const AndroidEnergyConsumerDescriptor & other) const9168   bool operator!=(const AndroidEnergyConsumerDescriptor& other) const { return !(*this == other); }
9169 
9170   bool ParseFromArray(const void*, size_t) override;
9171   std::string SerializeAsString() const override;
9172   std::vector<uint8_t> SerializeAsArray() const override;
9173   void Serialize(::protozero::Message*) const;
9174 
energy_consumers() const9175   const std::vector<AndroidEnergyConsumer>& energy_consumers() const { return energy_consumers_; }
mutable_energy_consumers()9176   std::vector<AndroidEnergyConsumer>* mutable_energy_consumers() { return &energy_consumers_; }
9177   int energy_consumers_size() const;
9178   void clear_energy_consumers();
9179   AndroidEnergyConsumer* add_energy_consumers();
9180 
9181  private:
9182   std::vector<AndroidEnergyConsumer> energy_consumers_;
9183 
9184   // Allows to preserve unknown protobuf fields for compatibility
9185   // with future versions of .proto files.
9186   std::string unknown_fields_;
9187 
9188   std::bitset<2> _has_field_{};
9189 };
9190 
9191 
9192 class PERFETTO_EXPORT AndroidEnergyConsumer : public ::protozero::CppMessageObj {
9193  public:
9194   enum FieldNumbers {
9195     kEnergyConsumerIdFieldNumber = 1,
9196     kOrdinalFieldNumber = 2,
9197     kTypeFieldNumber = 3,
9198     kNameFieldNumber = 4,
9199   };
9200 
9201   AndroidEnergyConsumer();
9202   ~AndroidEnergyConsumer() override;
9203   AndroidEnergyConsumer(AndroidEnergyConsumer&&) noexcept;
9204   AndroidEnergyConsumer& operator=(AndroidEnergyConsumer&&);
9205   AndroidEnergyConsumer(const AndroidEnergyConsumer&);
9206   AndroidEnergyConsumer& operator=(const AndroidEnergyConsumer&);
9207   bool operator==(const AndroidEnergyConsumer&) const;
operator !=(const AndroidEnergyConsumer & other) const9208   bool operator!=(const AndroidEnergyConsumer& other) const { return !(*this == other); }
9209 
9210   bool ParseFromArray(const void*, size_t) override;
9211   std::string SerializeAsString() const override;
9212   std::vector<uint8_t> SerializeAsArray() const override;
9213   void Serialize(::protozero::Message*) const;
9214 
has_energy_consumer_id() const9215   bool has_energy_consumer_id() const { return _has_field_[1]; }
energy_consumer_id() const9216   int32_t energy_consumer_id() const { return energy_consumer_id_; }
set_energy_consumer_id(int32_t value)9217   void set_energy_consumer_id(int32_t value) { energy_consumer_id_ = value; _has_field_.set(1); }
9218 
has_ordinal() const9219   bool has_ordinal() const { return _has_field_[2]; }
ordinal() const9220   int32_t ordinal() const { return ordinal_; }
set_ordinal(int32_t value)9221   void set_ordinal(int32_t value) { ordinal_ = value; _has_field_.set(2); }
9222 
has_type() const9223   bool has_type() const { return _has_field_[3]; }
type() const9224   const std::string& type() const { return type_; }
set_type(const std::string & value)9225   void set_type(const std::string& value) { type_ = value; _has_field_.set(3); }
9226 
has_name() const9227   bool has_name() const { return _has_field_[4]; }
name() const9228   const std::string& name() const { return name_; }
set_name(const std::string & value)9229   void set_name(const std::string& value) { name_ = value; _has_field_.set(4); }
9230 
9231  private:
9232   int32_t energy_consumer_id_{};
9233   int32_t ordinal_{};
9234   std::string type_{};
9235   std::string name_{};
9236 
9237   // Allows to preserve unknown protobuf fields for compatibility
9238   // with future versions of .proto files.
9239   std::string unknown_fields_;
9240 
9241   std::bitset<5> _has_field_{};
9242 };
9243 
9244 }  // namespace perfetto
9245 }  // namespace protos
9246 }  // namespace gen
9247 
9248 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_ENERGY_CONSUMER_DESCRIPTOR_PROTO_CPP_H_
9249 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
9250 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
9251 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
9252 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
9253 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
9254 #if defined(__GNUC__) || defined(__clang__)
9255 #pragma GCC diagnostic push
9256 #pragma GCC diagnostic ignored "-Wfloat-equal"
9257 #endif
9258 // gen_amalgamated expanded: #include "protos/perfetto/common/android_energy_consumer_descriptor.gen.h"
9259 
9260 namespace perfetto {
9261 namespace protos {
9262 namespace gen {
9263 
9264 AndroidEnergyConsumerDescriptor::AndroidEnergyConsumerDescriptor() = default;
9265 AndroidEnergyConsumerDescriptor::~AndroidEnergyConsumerDescriptor() = default;
9266 AndroidEnergyConsumerDescriptor::AndroidEnergyConsumerDescriptor(const AndroidEnergyConsumerDescriptor&) = default;
9267 AndroidEnergyConsumerDescriptor& AndroidEnergyConsumerDescriptor::operator=(const AndroidEnergyConsumerDescriptor&) = default;
9268 AndroidEnergyConsumerDescriptor::AndroidEnergyConsumerDescriptor(AndroidEnergyConsumerDescriptor&&) noexcept = default;
9269 AndroidEnergyConsumerDescriptor& AndroidEnergyConsumerDescriptor::operator=(AndroidEnergyConsumerDescriptor&&) = default;
9270 
operator ==(const AndroidEnergyConsumerDescriptor & other) const9271 bool AndroidEnergyConsumerDescriptor::operator==(const AndroidEnergyConsumerDescriptor& other) const {
9272   return unknown_fields_ == other.unknown_fields_
9273    && energy_consumers_ == other.energy_consumers_;
9274 }
9275 
energy_consumers_size() const9276 int AndroidEnergyConsumerDescriptor::energy_consumers_size() const { return static_cast<int>(energy_consumers_.size()); }
clear_energy_consumers()9277 void AndroidEnergyConsumerDescriptor::clear_energy_consumers() { energy_consumers_.clear(); }
add_energy_consumers()9278 AndroidEnergyConsumer* AndroidEnergyConsumerDescriptor::add_energy_consumers() { energy_consumers_.emplace_back(); return &energy_consumers_.back(); }
ParseFromArray(const void * raw,size_t size)9279 bool AndroidEnergyConsumerDescriptor::ParseFromArray(const void* raw, size_t size) {
9280   energy_consumers_.clear();
9281   unknown_fields_.clear();
9282   bool packed_error = false;
9283 
9284   ::protozero::ProtoDecoder dec(raw, size);
9285   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
9286     if (field.id() < _has_field_.size()) {
9287       _has_field_.set(field.id());
9288     }
9289     switch (field.id()) {
9290       case 1 /* energy_consumers */:
9291         energy_consumers_.emplace_back();
9292         energy_consumers_.back().ParseFromArray(field.data(), field.size());
9293         break;
9294       default:
9295         field.SerializeAndAppendTo(&unknown_fields_);
9296         break;
9297     }
9298   }
9299   return !packed_error && !dec.bytes_left();
9300 }
9301 
SerializeAsString() const9302 std::string AndroidEnergyConsumerDescriptor::SerializeAsString() const {
9303   ::protozero::HeapBuffered<::protozero::Message> msg;
9304   Serialize(msg.get());
9305   return msg.SerializeAsString();
9306 }
9307 
SerializeAsArray() const9308 std::vector<uint8_t> AndroidEnergyConsumerDescriptor::SerializeAsArray() const {
9309   ::protozero::HeapBuffered<::protozero::Message> msg;
9310   Serialize(msg.get());
9311   return msg.SerializeAsArray();
9312 }
9313 
Serialize(::protozero::Message * msg) const9314 void AndroidEnergyConsumerDescriptor::Serialize(::protozero::Message* msg) const {
9315   // Field 1: energy_consumers
9316   for (auto& it : energy_consumers_) {
9317     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
9318   }
9319 
9320   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
9321 }
9322 
9323 
9324 AndroidEnergyConsumer::AndroidEnergyConsumer() = default;
9325 AndroidEnergyConsumer::~AndroidEnergyConsumer() = default;
9326 AndroidEnergyConsumer::AndroidEnergyConsumer(const AndroidEnergyConsumer&) = default;
9327 AndroidEnergyConsumer& AndroidEnergyConsumer::operator=(const AndroidEnergyConsumer&) = default;
9328 AndroidEnergyConsumer::AndroidEnergyConsumer(AndroidEnergyConsumer&&) noexcept = default;
9329 AndroidEnergyConsumer& AndroidEnergyConsumer::operator=(AndroidEnergyConsumer&&) = default;
9330 
operator ==(const AndroidEnergyConsumer & other) const9331 bool AndroidEnergyConsumer::operator==(const AndroidEnergyConsumer& other) const {
9332   return unknown_fields_ == other.unknown_fields_
9333    && energy_consumer_id_ == other.energy_consumer_id_
9334    && ordinal_ == other.ordinal_
9335    && type_ == other.type_
9336    && name_ == other.name_;
9337 }
9338 
ParseFromArray(const void * raw,size_t size)9339 bool AndroidEnergyConsumer::ParseFromArray(const void* raw, size_t size) {
9340   unknown_fields_.clear();
9341   bool packed_error = false;
9342 
9343   ::protozero::ProtoDecoder dec(raw, size);
9344   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
9345     if (field.id() < _has_field_.size()) {
9346       _has_field_.set(field.id());
9347     }
9348     switch (field.id()) {
9349       case 1 /* energy_consumer_id */:
9350         field.get(&energy_consumer_id_);
9351         break;
9352       case 2 /* ordinal */:
9353         field.get(&ordinal_);
9354         break;
9355       case 3 /* type */:
9356         field.get(&type_);
9357         break;
9358       case 4 /* name */:
9359         field.get(&name_);
9360         break;
9361       default:
9362         field.SerializeAndAppendTo(&unknown_fields_);
9363         break;
9364     }
9365   }
9366   return !packed_error && !dec.bytes_left();
9367 }
9368 
SerializeAsString() const9369 std::string AndroidEnergyConsumer::SerializeAsString() const {
9370   ::protozero::HeapBuffered<::protozero::Message> msg;
9371   Serialize(msg.get());
9372   return msg.SerializeAsString();
9373 }
9374 
SerializeAsArray() const9375 std::vector<uint8_t> AndroidEnergyConsumer::SerializeAsArray() const {
9376   ::protozero::HeapBuffered<::protozero::Message> msg;
9377   Serialize(msg.get());
9378   return msg.SerializeAsArray();
9379 }
9380 
Serialize(::protozero::Message * msg) const9381 void AndroidEnergyConsumer::Serialize(::protozero::Message* msg) const {
9382   // Field 1: energy_consumer_id
9383   if (_has_field_[1]) {
9384     msg->AppendVarInt(1, energy_consumer_id_);
9385   }
9386 
9387   // Field 2: ordinal
9388   if (_has_field_[2]) {
9389     msg->AppendVarInt(2, ordinal_);
9390   }
9391 
9392   // Field 3: type
9393   if (_has_field_[3]) {
9394     msg->AppendString(3, type_);
9395   }
9396 
9397   // Field 4: name
9398   if (_has_field_[4]) {
9399     msg->AppendString(4, name_);
9400   }
9401 
9402   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
9403 }
9404 
9405 }  // namespace perfetto
9406 }  // namespace protos
9407 }  // namespace gen
9408 #if defined(__GNUC__) || defined(__clang__)
9409 #pragma GCC diagnostic pop
9410 #endif
9411 // gen_amalgamated begin source: gen/protos/perfetto/common/android_log_constants.gen.cc
9412 // gen_amalgamated begin header: gen/protos/perfetto/common/android_log_constants.gen.h
9413 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
9414 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_LOG_CONSTANTS_PROTO_CPP_H_
9415 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_LOG_CONSTANTS_PROTO_CPP_H_
9416 
9417 #include <stdint.h>
9418 #include <bitset>
9419 #include <vector>
9420 #include <string>
9421 #include <type_traits>
9422 
9423 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
9424 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
9425 // gen_amalgamated expanded: #include "perfetto/base/export.h"
9426 
9427 namespace perfetto {
9428 namespace protos {
9429 namespace gen {
9430 enum AndroidLogId : int;
9431 enum AndroidLogPriority : int;
9432 }  // namespace perfetto
9433 }  // namespace protos
9434 }  // namespace gen
9435 
9436 namespace protozero {
9437 class Message;
9438 }  // namespace protozero
9439 
9440 namespace perfetto {
9441 namespace protos {
9442 namespace gen {
9443 enum AndroidLogId : int {
9444   LID_DEFAULT = 0,
9445   LID_RADIO = 1,
9446   LID_EVENTS = 2,
9447   LID_SYSTEM = 3,
9448   LID_CRASH = 4,
9449   LID_STATS = 5,
9450   LID_SECURITY = 6,
9451   LID_KERNEL = 7,
9452 };
9453 enum AndroidLogPriority : int {
9454   PRIO_UNSPECIFIED = 0,
9455   PRIO_UNUSED = 1,
9456   PRIO_VERBOSE = 2,
9457   PRIO_DEBUG = 3,
9458   PRIO_INFO = 4,
9459   PRIO_WARN = 5,
9460   PRIO_ERROR = 6,
9461   PRIO_FATAL = 7,
9462 };
9463 }  // namespace perfetto
9464 }  // namespace protos
9465 }  // namespace gen
9466 
9467 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_LOG_CONSTANTS_PROTO_CPP_H_
9468 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
9469 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
9470 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
9471 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
9472 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
9473 #if defined(__GNUC__) || defined(__clang__)
9474 #pragma GCC diagnostic push
9475 #pragma GCC diagnostic ignored "-Wfloat-equal"
9476 #endif
9477 // gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
9478 
9479 namespace perfetto {
9480 namespace protos {
9481 namespace gen {
9482 }  // namespace perfetto
9483 }  // namespace protos
9484 }  // namespace gen
9485 #if defined(__GNUC__) || defined(__clang__)
9486 #pragma GCC diagnostic pop
9487 #endif
9488 // gen_amalgamated begin source: gen/protos/perfetto/common/builtin_clock.gen.cc
9489 // gen_amalgamated begin header: gen/protos/perfetto/common/builtin_clock.gen.h
9490 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
9491 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_BUILTIN_CLOCK_PROTO_CPP_H_
9492 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_BUILTIN_CLOCK_PROTO_CPP_H_
9493 
9494 #include <stdint.h>
9495 #include <bitset>
9496 #include <vector>
9497 #include <string>
9498 #include <type_traits>
9499 
9500 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
9501 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
9502 // gen_amalgamated expanded: #include "perfetto/base/export.h"
9503 
9504 namespace perfetto {
9505 namespace protos {
9506 namespace gen {
9507 enum BuiltinClock : int;
9508 }  // namespace perfetto
9509 }  // namespace protos
9510 }  // namespace gen
9511 
9512 namespace protozero {
9513 class Message;
9514 }  // namespace protozero
9515 
9516 namespace perfetto {
9517 namespace protos {
9518 namespace gen {
9519 enum BuiltinClock : int {
9520   BUILTIN_CLOCK_UNKNOWN = 0,
9521   BUILTIN_CLOCK_REALTIME = 1,
9522   BUILTIN_CLOCK_REALTIME_COARSE = 2,
9523   BUILTIN_CLOCK_MONOTONIC = 3,
9524   BUILTIN_CLOCK_MONOTONIC_COARSE = 4,
9525   BUILTIN_CLOCK_MONOTONIC_RAW = 5,
9526   BUILTIN_CLOCK_BOOTTIME = 6,
9527   BUILTIN_CLOCK_MAX_ID = 63,
9528 };
9529 }  // namespace perfetto
9530 }  // namespace protos
9531 }  // namespace gen
9532 
9533 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_BUILTIN_CLOCK_PROTO_CPP_H_
9534 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
9535 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
9536 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
9537 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
9538 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
9539 #if defined(__GNUC__) || defined(__clang__)
9540 #pragma GCC diagnostic push
9541 #pragma GCC diagnostic ignored "-Wfloat-equal"
9542 #endif
9543 // gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"
9544 
9545 namespace perfetto {
9546 namespace protos {
9547 namespace gen {
9548 }  // namespace perfetto
9549 }  // namespace protos
9550 }  // namespace gen
9551 #if defined(__GNUC__) || defined(__clang__)
9552 #pragma GCC diagnostic pop
9553 #endif
9554 // gen_amalgamated begin source: gen/protos/perfetto/common/commit_data_request.gen.cc
9555 // gen_amalgamated begin header: gen/protos/perfetto/common/commit_data_request.gen.h
9556 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
9557 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_COMMIT_DATA_REQUEST_PROTO_CPP_H_
9558 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_COMMIT_DATA_REQUEST_PROTO_CPP_H_
9559 
9560 #include <stdint.h>
9561 #include <bitset>
9562 #include <vector>
9563 #include <string>
9564 #include <type_traits>
9565 
9566 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
9567 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
9568 // gen_amalgamated expanded: #include "perfetto/base/export.h"
9569 
9570 namespace perfetto {
9571 namespace protos {
9572 namespace gen {
9573 class CommitDataRequest;
9574 class CommitDataRequest_ChunkToPatch;
9575 class CommitDataRequest_ChunkToPatch_Patch;
9576 class CommitDataRequest_ChunksToMove;
9577 }  // namespace perfetto
9578 }  // namespace protos
9579 }  // namespace gen
9580 
9581 namespace protozero {
9582 class Message;
9583 }  // namespace protozero
9584 
9585 namespace perfetto {
9586 namespace protos {
9587 namespace gen {
9588 
9589 class PERFETTO_EXPORT CommitDataRequest : public ::protozero::CppMessageObj {
9590  public:
9591   using ChunksToMove = CommitDataRequest_ChunksToMove;
9592   using ChunkToPatch = CommitDataRequest_ChunkToPatch;
9593   enum FieldNumbers {
9594     kChunksToMoveFieldNumber = 1,
9595     kChunksToPatchFieldNumber = 2,
9596     kFlushRequestIdFieldNumber = 3,
9597   };
9598 
9599   CommitDataRequest();
9600   ~CommitDataRequest() override;
9601   CommitDataRequest(CommitDataRequest&&) noexcept;
9602   CommitDataRequest& operator=(CommitDataRequest&&);
9603   CommitDataRequest(const CommitDataRequest&);
9604   CommitDataRequest& operator=(const CommitDataRequest&);
9605   bool operator==(const CommitDataRequest&) const;
operator !=(const CommitDataRequest & other) const9606   bool operator!=(const CommitDataRequest& other) const { return !(*this == other); }
9607 
9608   bool ParseFromArray(const void*, size_t) override;
9609   std::string SerializeAsString() const override;
9610   std::vector<uint8_t> SerializeAsArray() const override;
9611   void Serialize(::protozero::Message*) const;
9612 
chunks_to_move() const9613   const std::vector<CommitDataRequest_ChunksToMove>& chunks_to_move() const { return chunks_to_move_; }
mutable_chunks_to_move()9614   std::vector<CommitDataRequest_ChunksToMove>* mutable_chunks_to_move() { return &chunks_to_move_; }
9615   int chunks_to_move_size() const;
9616   void clear_chunks_to_move();
9617   CommitDataRequest_ChunksToMove* add_chunks_to_move();
9618 
chunks_to_patch() const9619   const std::vector<CommitDataRequest_ChunkToPatch>& chunks_to_patch() const { return chunks_to_patch_; }
mutable_chunks_to_patch()9620   std::vector<CommitDataRequest_ChunkToPatch>* mutable_chunks_to_patch() { return &chunks_to_patch_; }
9621   int chunks_to_patch_size() const;
9622   void clear_chunks_to_patch();
9623   CommitDataRequest_ChunkToPatch* add_chunks_to_patch();
9624 
has_flush_request_id() const9625   bool has_flush_request_id() const { return _has_field_[3]; }
flush_request_id() const9626   uint64_t flush_request_id() const { return flush_request_id_; }
set_flush_request_id(uint64_t value)9627   void set_flush_request_id(uint64_t value) { flush_request_id_ = value; _has_field_.set(3); }
9628 
9629  private:
9630   std::vector<CommitDataRequest_ChunksToMove> chunks_to_move_;
9631   std::vector<CommitDataRequest_ChunkToPatch> chunks_to_patch_;
9632   uint64_t flush_request_id_{};
9633 
9634   // Allows to preserve unknown protobuf fields for compatibility
9635   // with future versions of .proto files.
9636   std::string unknown_fields_;
9637 
9638   std::bitset<4> _has_field_{};
9639 };
9640 
9641 
9642 class PERFETTO_EXPORT CommitDataRequest_ChunkToPatch : public ::protozero::CppMessageObj {
9643  public:
9644   using Patch = CommitDataRequest_ChunkToPatch_Patch;
9645   enum FieldNumbers {
9646     kTargetBufferFieldNumber = 1,
9647     kWriterIdFieldNumber = 2,
9648     kChunkIdFieldNumber = 3,
9649     kPatchesFieldNumber = 4,
9650     kHasMorePatchesFieldNumber = 5,
9651   };
9652 
9653   CommitDataRequest_ChunkToPatch();
9654   ~CommitDataRequest_ChunkToPatch() override;
9655   CommitDataRequest_ChunkToPatch(CommitDataRequest_ChunkToPatch&&) noexcept;
9656   CommitDataRequest_ChunkToPatch& operator=(CommitDataRequest_ChunkToPatch&&);
9657   CommitDataRequest_ChunkToPatch(const CommitDataRequest_ChunkToPatch&);
9658   CommitDataRequest_ChunkToPatch& operator=(const CommitDataRequest_ChunkToPatch&);
9659   bool operator==(const CommitDataRequest_ChunkToPatch&) const;
operator !=(const CommitDataRequest_ChunkToPatch & other) const9660   bool operator!=(const CommitDataRequest_ChunkToPatch& other) const { return !(*this == other); }
9661 
9662   bool ParseFromArray(const void*, size_t) override;
9663   std::string SerializeAsString() const override;
9664   std::vector<uint8_t> SerializeAsArray() const override;
9665   void Serialize(::protozero::Message*) const;
9666 
has_target_buffer() const9667   bool has_target_buffer() const { return _has_field_[1]; }
target_buffer() const9668   uint32_t target_buffer() const { return target_buffer_; }
set_target_buffer(uint32_t value)9669   void set_target_buffer(uint32_t value) { target_buffer_ = value; _has_field_.set(1); }
9670 
has_writer_id() const9671   bool has_writer_id() const { return _has_field_[2]; }
writer_id() const9672   uint32_t writer_id() const { return writer_id_; }
set_writer_id(uint32_t value)9673   void set_writer_id(uint32_t value) { writer_id_ = value; _has_field_.set(2); }
9674 
has_chunk_id() const9675   bool has_chunk_id() const { return _has_field_[3]; }
chunk_id() const9676   uint32_t chunk_id() const { return chunk_id_; }
set_chunk_id(uint32_t value)9677   void set_chunk_id(uint32_t value) { chunk_id_ = value; _has_field_.set(3); }
9678 
patches() const9679   const std::vector<CommitDataRequest_ChunkToPatch_Patch>& patches() const { return patches_; }
mutable_patches()9680   std::vector<CommitDataRequest_ChunkToPatch_Patch>* mutable_patches() { return &patches_; }
9681   int patches_size() const;
9682   void clear_patches();
9683   CommitDataRequest_ChunkToPatch_Patch* add_patches();
9684 
has_has_more_patches() const9685   bool has_has_more_patches() const { return _has_field_[5]; }
has_more_patches() const9686   bool has_more_patches() const { return has_more_patches_; }
set_has_more_patches(bool value)9687   void set_has_more_patches(bool value) { has_more_patches_ = value; _has_field_.set(5); }
9688 
9689  private:
9690   uint32_t target_buffer_{};
9691   uint32_t writer_id_{};
9692   uint32_t chunk_id_{};
9693   std::vector<CommitDataRequest_ChunkToPatch_Patch> patches_;
9694   bool has_more_patches_{};
9695 
9696   // Allows to preserve unknown protobuf fields for compatibility
9697   // with future versions of .proto files.
9698   std::string unknown_fields_;
9699 
9700   std::bitset<6> _has_field_{};
9701 };
9702 
9703 
9704 class PERFETTO_EXPORT CommitDataRequest_ChunkToPatch_Patch : public ::protozero::CppMessageObj {
9705  public:
9706   enum FieldNumbers {
9707     kOffsetFieldNumber = 1,
9708     kDataFieldNumber = 2,
9709   };
9710 
9711   CommitDataRequest_ChunkToPatch_Patch();
9712   ~CommitDataRequest_ChunkToPatch_Patch() override;
9713   CommitDataRequest_ChunkToPatch_Patch(CommitDataRequest_ChunkToPatch_Patch&&) noexcept;
9714   CommitDataRequest_ChunkToPatch_Patch& operator=(CommitDataRequest_ChunkToPatch_Patch&&);
9715   CommitDataRequest_ChunkToPatch_Patch(const CommitDataRequest_ChunkToPatch_Patch&);
9716   CommitDataRequest_ChunkToPatch_Patch& operator=(const CommitDataRequest_ChunkToPatch_Patch&);
9717   bool operator==(const CommitDataRequest_ChunkToPatch_Patch&) const;
operator !=(const CommitDataRequest_ChunkToPatch_Patch & other) const9718   bool operator!=(const CommitDataRequest_ChunkToPatch_Patch& other) const { return !(*this == other); }
9719 
9720   bool ParseFromArray(const void*, size_t) override;
9721   std::string SerializeAsString() const override;
9722   std::vector<uint8_t> SerializeAsArray() const override;
9723   void Serialize(::protozero::Message*) const;
9724 
has_offset() const9725   bool has_offset() const { return _has_field_[1]; }
offset() const9726   uint32_t offset() const { return offset_; }
set_offset(uint32_t value)9727   void set_offset(uint32_t value) { offset_ = value; _has_field_.set(1); }
9728 
has_data() const9729   bool has_data() const { return _has_field_[2]; }
data() const9730   const std::string& data() const { return data_; }
set_data(const std::string & value)9731   void set_data(const std::string& value) { data_ = value; _has_field_.set(2); }
set_data(const void * p,size_t s)9732   void set_data(const void* p, size_t s) { data_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(2); }
9733 
9734  private:
9735   uint32_t offset_{};
9736   std::string data_{};
9737 
9738   // Allows to preserve unknown protobuf fields for compatibility
9739   // with future versions of .proto files.
9740   std::string unknown_fields_;
9741 
9742   std::bitset<3> _has_field_{};
9743 };
9744 
9745 
9746 class PERFETTO_EXPORT CommitDataRequest_ChunksToMove : public ::protozero::CppMessageObj {
9747  public:
9748   enum FieldNumbers {
9749     kPageFieldNumber = 1,
9750     kChunkFieldNumber = 2,
9751     kTargetBufferFieldNumber = 3,
9752   };
9753 
9754   CommitDataRequest_ChunksToMove();
9755   ~CommitDataRequest_ChunksToMove() override;
9756   CommitDataRequest_ChunksToMove(CommitDataRequest_ChunksToMove&&) noexcept;
9757   CommitDataRequest_ChunksToMove& operator=(CommitDataRequest_ChunksToMove&&);
9758   CommitDataRequest_ChunksToMove(const CommitDataRequest_ChunksToMove&);
9759   CommitDataRequest_ChunksToMove& operator=(const CommitDataRequest_ChunksToMove&);
9760   bool operator==(const CommitDataRequest_ChunksToMove&) const;
operator !=(const CommitDataRequest_ChunksToMove & other) const9761   bool operator!=(const CommitDataRequest_ChunksToMove& other) const { return !(*this == other); }
9762 
9763   bool ParseFromArray(const void*, size_t) override;
9764   std::string SerializeAsString() const override;
9765   std::vector<uint8_t> SerializeAsArray() const override;
9766   void Serialize(::protozero::Message*) const;
9767 
has_page() const9768   bool has_page() const { return _has_field_[1]; }
page() const9769   uint32_t page() const { return page_; }
set_page(uint32_t value)9770   void set_page(uint32_t value) { page_ = value; _has_field_.set(1); }
9771 
has_chunk() const9772   bool has_chunk() const { return _has_field_[2]; }
chunk() const9773   uint32_t chunk() const { return chunk_; }
set_chunk(uint32_t value)9774   void set_chunk(uint32_t value) { chunk_ = value; _has_field_.set(2); }
9775 
has_target_buffer() const9776   bool has_target_buffer() const { return _has_field_[3]; }
target_buffer() const9777   uint32_t target_buffer() const { return target_buffer_; }
set_target_buffer(uint32_t value)9778   void set_target_buffer(uint32_t value) { target_buffer_ = value; _has_field_.set(3); }
9779 
9780  private:
9781   uint32_t page_{};
9782   uint32_t chunk_{};
9783   uint32_t target_buffer_{};
9784 
9785   // Allows to preserve unknown protobuf fields for compatibility
9786   // with future versions of .proto files.
9787   std::string unknown_fields_;
9788 
9789   std::bitset<4> _has_field_{};
9790 };
9791 
9792 }  // namespace perfetto
9793 }  // namespace protos
9794 }  // namespace gen
9795 
9796 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_COMMIT_DATA_REQUEST_PROTO_CPP_H_
9797 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
9798 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
9799 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
9800 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
9801 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
9802 #if defined(__GNUC__) || defined(__clang__)
9803 #pragma GCC diagnostic push
9804 #pragma GCC diagnostic ignored "-Wfloat-equal"
9805 #endif
9806 // gen_amalgamated expanded: #include "protos/perfetto/common/commit_data_request.gen.h"
9807 
9808 namespace perfetto {
9809 namespace protos {
9810 namespace gen {
9811 
9812 CommitDataRequest::CommitDataRequest() = default;
9813 CommitDataRequest::~CommitDataRequest() = default;
9814 CommitDataRequest::CommitDataRequest(const CommitDataRequest&) = default;
9815 CommitDataRequest& CommitDataRequest::operator=(const CommitDataRequest&) = default;
9816 CommitDataRequest::CommitDataRequest(CommitDataRequest&&) noexcept = default;
9817 CommitDataRequest& CommitDataRequest::operator=(CommitDataRequest&&) = default;
9818 
operator ==(const CommitDataRequest & other) const9819 bool CommitDataRequest::operator==(const CommitDataRequest& other) const {
9820   return unknown_fields_ == other.unknown_fields_
9821    && chunks_to_move_ == other.chunks_to_move_
9822    && chunks_to_patch_ == other.chunks_to_patch_
9823    && flush_request_id_ == other.flush_request_id_;
9824 }
9825 
chunks_to_move_size() const9826 int CommitDataRequest::chunks_to_move_size() const { return static_cast<int>(chunks_to_move_.size()); }
clear_chunks_to_move()9827 void CommitDataRequest::clear_chunks_to_move() { chunks_to_move_.clear(); }
add_chunks_to_move()9828 CommitDataRequest_ChunksToMove* CommitDataRequest::add_chunks_to_move() { chunks_to_move_.emplace_back(); return &chunks_to_move_.back(); }
chunks_to_patch_size() const9829 int CommitDataRequest::chunks_to_patch_size() const { return static_cast<int>(chunks_to_patch_.size()); }
clear_chunks_to_patch()9830 void CommitDataRequest::clear_chunks_to_patch() { chunks_to_patch_.clear(); }
add_chunks_to_patch()9831 CommitDataRequest_ChunkToPatch* CommitDataRequest::add_chunks_to_patch() { chunks_to_patch_.emplace_back(); return &chunks_to_patch_.back(); }
ParseFromArray(const void * raw,size_t size)9832 bool CommitDataRequest::ParseFromArray(const void* raw, size_t size) {
9833   chunks_to_move_.clear();
9834   chunks_to_patch_.clear();
9835   unknown_fields_.clear();
9836   bool packed_error = false;
9837 
9838   ::protozero::ProtoDecoder dec(raw, size);
9839   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
9840     if (field.id() < _has_field_.size()) {
9841       _has_field_.set(field.id());
9842     }
9843     switch (field.id()) {
9844       case 1 /* chunks_to_move */:
9845         chunks_to_move_.emplace_back();
9846         chunks_to_move_.back().ParseFromArray(field.data(), field.size());
9847         break;
9848       case 2 /* chunks_to_patch */:
9849         chunks_to_patch_.emplace_back();
9850         chunks_to_patch_.back().ParseFromArray(field.data(), field.size());
9851         break;
9852       case 3 /* flush_request_id */:
9853         field.get(&flush_request_id_);
9854         break;
9855       default:
9856         field.SerializeAndAppendTo(&unknown_fields_);
9857         break;
9858     }
9859   }
9860   return !packed_error && !dec.bytes_left();
9861 }
9862 
SerializeAsString() const9863 std::string CommitDataRequest::SerializeAsString() const {
9864   ::protozero::HeapBuffered<::protozero::Message> msg;
9865   Serialize(msg.get());
9866   return msg.SerializeAsString();
9867 }
9868 
SerializeAsArray() const9869 std::vector<uint8_t> CommitDataRequest::SerializeAsArray() const {
9870   ::protozero::HeapBuffered<::protozero::Message> msg;
9871   Serialize(msg.get());
9872   return msg.SerializeAsArray();
9873 }
9874 
Serialize(::protozero::Message * msg) const9875 void CommitDataRequest::Serialize(::protozero::Message* msg) const {
9876   // Field 1: chunks_to_move
9877   for (auto& it : chunks_to_move_) {
9878     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
9879   }
9880 
9881   // Field 2: chunks_to_patch
9882   for (auto& it : chunks_to_patch_) {
9883     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
9884   }
9885 
9886   // Field 3: flush_request_id
9887   if (_has_field_[3]) {
9888     msg->AppendVarInt(3, flush_request_id_);
9889   }
9890 
9891   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
9892 }
9893 
9894 
9895 CommitDataRequest_ChunkToPatch::CommitDataRequest_ChunkToPatch() = default;
9896 CommitDataRequest_ChunkToPatch::~CommitDataRequest_ChunkToPatch() = default;
9897 CommitDataRequest_ChunkToPatch::CommitDataRequest_ChunkToPatch(const CommitDataRequest_ChunkToPatch&) = default;
9898 CommitDataRequest_ChunkToPatch& CommitDataRequest_ChunkToPatch::operator=(const CommitDataRequest_ChunkToPatch&) = default;
9899 CommitDataRequest_ChunkToPatch::CommitDataRequest_ChunkToPatch(CommitDataRequest_ChunkToPatch&&) noexcept = default;
9900 CommitDataRequest_ChunkToPatch& CommitDataRequest_ChunkToPatch::operator=(CommitDataRequest_ChunkToPatch&&) = default;
9901 
operator ==(const CommitDataRequest_ChunkToPatch & other) const9902 bool CommitDataRequest_ChunkToPatch::operator==(const CommitDataRequest_ChunkToPatch& other) const {
9903   return unknown_fields_ == other.unknown_fields_
9904    && target_buffer_ == other.target_buffer_
9905    && writer_id_ == other.writer_id_
9906    && chunk_id_ == other.chunk_id_
9907    && patches_ == other.patches_
9908    && has_more_patches_ == other.has_more_patches_;
9909 }
9910 
patches_size() const9911 int CommitDataRequest_ChunkToPatch::patches_size() const { return static_cast<int>(patches_.size()); }
clear_patches()9912 void CommitDataRequest_ChunkToPatch::clear_patches() { patches_.clear(); }
add_patches()9913 CommitDataRequest_ChunkToPatch_Patch* CommitDataRequest_ChunkToPatch::add_patches() { patches_.emplace_back(); return &patches_.back(); }
ParseFromArray(const void * raw,size_t size)9914 bool CommitDataRequest_ChunkToPatch::ParseFromArray(const void* raw, size_t size) {
9915   patches_.clear();
9916   unknown_fields_.clear();
9917   bool packed_error = false;
9918 
9919   ::protozero::ProtoDecoder dec(raw, size);
9920   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
9921     if (field.id() < _has_field_.size()) {
9922       _has_field_.set(field.id());
9923     }
9924     switch (field.id()) {
9925       case 1 /* target_buffer */:
9926         field.get(&target_buffer_);
9927         break;
9928       case 2 /* writer_id */:
9929         field.get(&writer_id_);
9930         break;
9931       case 3 /* chunk_id */:
9932         field.get(&chunk_id_);
9933         break;
9934       case 4 /* patches */:
9935         patches_.emplace_back();
9936         patches_.back().ParseFromArray(field.data(), field.size());
9937         break;
9938       case 5 /* has_more_patches */:
9939         field.get(&has_more_patches_);
9940         break;
9941       default:
9942         field.SerializeAndAppendTo(&unknown_fields_);
9943         break;
9944     }
9945   }
9946   return !packed_error && !dec.bytes_left();
9947 }
9948 
SerializeAsString() const9949 std::string CommitDataRequest_ChunkToPatch::SerializeAsString() const {
9950   ::protozero::HeapBuffered<::protozero::Message> msg;
9951   Serialize(msg.get());
9952   return msg.SerializeAsString();
9953 }
9954 
SerializeAsArray() const9955 std::vector<uint8_t> CommitDataRequest_ChunkToPatch::SerializeAsArray() const {
9956   ::protozero::HeapBuffered<::protozero::Message> msg;
9957   Serialize(msg.get());
9958   return msg.SerializeAsArray();
9959 }
9960 
Serialize(::protozero::Message * msg) const9961 void CommitDataRequest_ChunkToPatch::Serialize(::protozero::Message* msg) const {
9962   // Field 1: target_buffer
9963   if (_has_field_[1]) {
9964     msg->AppendVarInt(1, target_buffer_);
9965   }
9966 
9967   // Field 2: writer_id
9968   if (_has_field_[2]) {
9969     msg->AppendVarInt(2, writer_id_);
9970   }
9971 
9972   // Field 3: chunk_id
9973   if (_has_field_[3]) {
9974     msg->AppendVarInt(3, chunk_id_);
9975   }
9976 
9977   // Field 4: patches
9978   for (auto& it : patches_) {
9979     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
9980   }
9981 
9982   // Field 5: has_more_patches
9983   if (_has_field_[5]) {
9984     msg->AppendTinyVarInt(5, has_more_patches_);
9985   }
9986 
9987   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
9988 }
9989 
9990 
9991 CommitDataRequest_ChunkToPatch_Patch::CommitDataRequest_ChunkToPatch_Patch() = default;
9992 CommitDataRequest_ChunkToPatch_Patch::~CommitDataRequest_ChunkToPatch_Patch() = default;
9993 CommitDataRequest_ChunkToPatch_Patch::CommitDataRequest_ChunkToPatch_Patch(const CommitDataRequest_ChunkToPatch_Patch&) = default;
9994 CommitDataRequest_ChunkToPatch_Patch& CommitDataRequest_ChunkToPatch_Patch::operator=(const CommitDataRequest_ChunkToPatch_Patch&) = default;
9995 CommitDataRequest_ChunkToPatch_Patch::CommitDataRequest_ChunkToPatch_Patch(CommitDataRequest_ChunkToPatch_Patch&&) noexcept = default;
9996 CommitDataRequest_ChunkToPatch_Patch& CommitDataRequest_ChunkToPatch_Patch::operator=(CommitDataRequest_ChunkToPatch_Patch&&) = default;
9997 
operator ==(const CommitDataRequest_ChunkToPatch_Patch & other) const9998 bool CommitDataRequest_ChunkToPatch_Patch::operator==(const CommitDataRequest_ChunkToPatch_Patch& other) const {
9999   return unknown_fields_ == other.unknown_fields_
10000    && offset_ == other.offset_
10001    && data_ == other.data_;
10002 }
10003 
ParseFromArray(const void * raw,size_t size)10004 bool CommitDataRequest_ChunkToPatch_Patch::ParseFromArray(const void* raw, size_t size) {
10005   unknown_fields_.clear();
10006   bool packed_error = false;
10007 
10008   ::protozero::ProtoDecoder dec(raw, size);
10009   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
10010     if (field.id() < _has_field_.size()) {
10011       _has_field_.set(field.id());
10012     }
10013     switch (field.id()) {
10014       case 1 /* offset */:
10015         field.get(&offset_);
10016         break;
10017       case 2 /* data */:
10018         field.get(&data_);
10019         break;
10020       default:
10021         field.SerializeAndAppendTo(&unknown_fields_);
10022         break;
10023     }
10024   }
10025   return !packed_error && !dec.bytes_left();
10026 }
10027 
SerializeAsString() const10028 std::string CommitDataRequest_ChunkToPatch_Patch::SerializeAsString() const {
10029   ::protozero::HeapBuffered<::protozero::Message> msg;
10030   Serialize(msg.get());
10031   return msg.SerializeAsString();
10032 }
10033 
SerializeAsArray() const10034 std::vector<uint8_t> CommitDataRequest_ChunkToPatch_Patch::SerializeAsArray() const {
10035   ::protozero::HeapBuffered<::protozero::Message> msg;
10036   Serialize(msg.get());
10037   return msg.SerializeAsArray();
10038 }
10039 
Serialize(::protozero::Message * msg) const10040 void CommitDataRequest_ChunkToPatch_Patch::Serialize(::protozero::Message* msg) const {
10041   // Field 1: offset
10042   if (_has_field_[1]) {
10043     msg->AppendVarInt(1, offset_);
10044   }
10045 
10046   // Field 2: data
10047   if (_has_field_[2]) {
10048     msg->AppendString(2, data_);
10049   }
10050 
10051   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
10052 }
10053 
10054 
10055 CommitDataRequest_ChunksToMove::CommitDataRequest_ChunksToMove() = default;
10056 CommitDataRequest_ChunksToMove::~CommitDataRequest_ChunksToMove() = default;
10057 CommitDataRequest_ChunksToMove::CommitDataRequest_ChunksToMove(const CommitDataRequest_ChunksToMove&) = default;
10058 CommitDataRequest_ChunksToMove& CommitDataRequest_ChunksToMove::operator=(const CommitDataRequest_ChunksToMove&) = default;
10059 CommitDataRequest_ChunksToMove::CommitDataRequest_ChunksToMove(CommitDataRequest_ChunksToMove&&) noexcept = default;
10060 CommitDataRequest_ChunksToMove& CommitDataRequest_ChunksToMove::operator=(CommitDataRequest_ChunksToMove&&) = default;
10061 
operator ==(const CommitDataRequest_ChunksToMove & other) const10062 bool CommitDataRequest_ChunksToMove::operator==(const CommitDataRequest_ChunksToMove& other) const {
10063   return unknown_fields_ == other.unknown_fields_
10064    && page_ == other.page_
10065    && chunk_ == other.chunk_
10066    && target_buffer_ == other.target_buffer_;
10067 }
10068 
ParseFromArray(const void * raw,size_t size)10069 bool CommitDataRequest_ChunksToMove::ParseFromArray(const void* raw, size_t size) {
10070   unknown_fields_.clear();
10071   bool packed_error = false;
10072 
10073   ::protozero::ProtoDecoder dec(raw, size);
10074   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
10075     if (field.id() < _has_field_.size()) {
10076       _has_field_.set(field.id());
10077     }
10078     switch (field.id()) {
10079       case 1 /* page */:
10080         field.get(&page_);
10081         break;
10082       case 2 /* chunk */:
10083         field.get(&chunk_);
10084         break;
10085       case 3 /* target_buffer */:
10086         field.get(&target_buffer_);
10087         break;
10088       default:
10089         field.SerializeAndAppendTo(&unknown_fields_);
10090         break;
10091     }
10092   }
10093   return !packed_error && !dec.bytes_left();
10094 }
10095 
SerializeAsString() const10096 std::string CommitDataRequest_ChunksToMove::SerializeAsString() const {
10097   ::protozero::HeapBuffered<::protozero::Message> msg;
10098   Serialize(msg.get());
10099   return msg.SerializeAsString();
10100 }
10101 
SerializeAsArray() const10102 std::vector<uint8_t> CommitDataRequest_ChunksToMove::SerializeAsArray() const {
10103   ::protozero::HeapBuffered<::protozero::Message> msg;
10104   Serialize(msg.get());
10105   return msg.SerializeAsArray();
10106 }
10107 
Serialize(::protozero::Message * msg) const10108 void CommitDataRequest_ChunksToMove::Serialize(::protozero::Message* msg) const {
10109   // Field 1: page
10110   if (_has_field_[1]) {
10111     msg->AppendVarInt(1, page_);
10112   }
10113 
10114   // Field 2: chunk
10115   if (_has_field_[2]) {
10116     msg->AppendVarInt(2, chunk_);
10117   }
10118 
10119   // Field 3: target_buffer
10120   if (_has_field_[3]) {
10121     msg->AppendVarInt(3, target_buffer_);
10122   }
10123 
10124   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
10125 }
10126 
10127 }  // namespace perfetto
10128 }  // namespace protos
10129 }  // namespace gen
10130 #if defined(__GNUC__) || defined(__clang__)
10131 #pragma GCC diagnostic pop
10132 #endif
10133 // gen_amalgamated begin source: gen/protos/perfetto/common/data_source_descriptor.gen.cc
10134 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
10135 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
10136 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
10137 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
10138 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
10139 #if defined(__GNUC__) || defined(__clang__)
10140 #pragma GCC diagnostic push
10141 #pragma GCC diagnostic ignored "-Wfloat-equal"
10142 #endif
10143 // gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
10144 
10145 namespace perfetto {
10146 namespace protos {
10147 namespace gen {
10148 
10149 DataSourceDescriptor::DataSourceDescriptor() = default;
10150 DataSourceDescriptor::~DataSourceDescriptor() = default;
10151 DataSourceDescriptor::DataSourceDescriptor(const DataSourceDescriptor&) = default;
10152 DataSourceDescriptor& DataSourceDescriptor::operator=(const DataSourceDescriptor&) = default;
10153 DataSourceDescriptor::DataSourceDescriptor(DataSourceDescriptor&&) noexcept = default;
10154 DataSourceDescriptor& DataSourceDescriptor::operator=(DataSourceDescriptor&&) = default;
10155 
operator ==(const DataSourceDescriptor & other) const10156 bool DataSourceDescriptor::operator==(const DataSourceDescriptor& other) const {
10157   return unknown_fields_ == other.unknown_fields_
10158    && name_ == other.name_
10159    && will_notify_on_stop_ == other.will_notify_on_stop_
10160    && will_notify_on_start_ == other.will_notify_on_start_
10161    && handles_incremental_state_clear_ == other.handles_incremental_state_clear_
10162    && gpu_counter_descriptor_ == other.gpu_counter_descriptor_
10163    && track_event_descriptor_ == other.track_event_descriptor_;
10164 }
10165 
ParseFromArray(const void * raw,size_t size)10166 bool DataSourceDescriptor::ParseFromArray(const void* raw, size_t size) {
10167   unknown_fields_.clear();
10168   bool packed_error = false;
10169 
10170   ::protozero::ProtoDecoder dec(raw, size);
10171   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
10172     if (field.id() < _has_field_.size()) {
10173       _has_field_.set(field.id());
10174     }
10175     switch (field.id()) {
10176       case 1 /* name */:
10177         field.get(&name_);
10178         break;
10179       case 2 /* will_notify_on_stop */:
10180         field.get(&will_notify_on_stop_);
10181         break;
10182       case 3 /* will_notify_on_start */:
10183         field.get(&will_notify_on_start_);
10184         break;
10185       case 4 /* handles_incremental_state_clear */:
10186         field.get(&handles_incremental_state_clear_);
10187         break;
10188       case 5 /* gpu_counter_descriptor */:
10189         gpu_counter_descriptor_ = field.as_std_string();
10190         break;
10191       case 6 /* track_event_descriptor */:
10192         track_event_descriptor_ = field.as_std_string();
10193         break;
10194       default:
10195         field.SerializeAndAppendTo(&unknown_fields_);
10196         break;
10197     }
10198   }
10199   return !packed_error && !dec.bytes_left();
10200 }
10201 
SerializeAsString() const10202 std::string DataSourceDescriptor::SerializeAsString() const {
10203   ::protozero::HeapBuffered<::protozero::Message> msg;
10204   Serialize(msg.get());
10205   return msg.SerializeAsString();
10206 }
10207 
SerializeAsArray() const10208 std::vector<uint8_t> DataSourceDescriptor::SerializeAsArray() const {
10209   ::protozero::HeapBuffered<::protozero::Message> msg;
10210   Serialize(msg.get());
10211   return msg.SerializeAsArray();
10212 }
10213 
Serialize(::protozero::Message * msg) const10214 void DataSourceDescriptor::Serialize(::protozero::Message* msg) const {
10215   // Field 1: name
10216   if (_has_field_[1]) {
10217     msg->AppendString(1, name_);
10218   }
10219 
10220   // Field 2: will_notify_on_stop
10221   if (_has_field_[2]) {
10222     msg->AppendTinyVarInt(2, will_notify_on_stop_);
10223   }
10224 
10225   // Field 3: will_notify_on_start
10226   if (_has_field_[3]) {
10227     msg->AppendTinyVarInt(3, will_notify_on_start_);
10228   }
10229 
10230   // Field 4: handles_incremental_state_clear
10231   if (_has_field_[4]) {
10232     msg->AppendTinyVarInt(4, handles_incremental_state_clear_);
10233   }
10234 
10235   // Field 5: gpu_counter_descriptor
10236   if (_has_field_[5]) {
10237     msg->AppendString(5, gpu_counter_descriptor_);
10238   }
10239 
10240   // Field 6: track_event_descriptor
10241   if (_has_field_[6]) {
10242     msg->AppendString(6, track_event_descriptor_);
10243   }
10244 
10245   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
10246 }
10247 
10248 }  // namespace perfetto
10249 }  // namespace protos
10250 }  // namespace gen
10251 #if defined(__GNUC__) || defined(__clang__)
10252 #pragma GCC diagnostic pop
10253 #endif
10254 // gen_amalgamated begin source: gen/protos/perfetto/common/descriptor.gen.cc
10255 // gen_amalgamated begin header: gen/protos/perfetto/common/descriptor.gen.h
10256 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
10257 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DESCRIPTOR_PROTO_CPP_H_
10258 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DESCRIPTOR_PROTO_CPP_H_
10259 
10260 #include <stdint.h>
10261 #include <bitset>
10262 #include <vector>
10263 #include <string>
10264 #include <type_traits>
10265 
10266 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
10267 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
10268 // gen_amalgamated expanded: #include "perfetto/base/export.h"
10269 
10270 namespace perfetto {
10271 namespace protos {
10272 namespace gen {
10273 class OneofOptions;
10274 class EnumValueDescriptorProto;
10275 class EnumDescriptorProto;
10276 class OneofDescriptorProto;
10277 class FieldDescriptorProto;
10278 class DescriptorProto;
10279 class DescriptorProto_ReservedRange;
10280 class FileDescriptorProto;
10281 class FileDescriptorSet;
10282 enum FieldDescriptorProto_Type : int;
10283 enum FieldDescriptorProto_Label : int;
10284 }  // namespace perfetto
10285 }  // namespace protos
10286 }  // namespace gen
10287 
10288 namespace protozero {
10289 class Message;
10290 }  // namespace protozero
10291 
10292 namespace perfetto {
10293 namespace protos {
10294 namespace gen {
10295 enum FieldDescriptorProto_Type : int {
10296   FieldDescriptorProto_Type_TYPE_DOUBLE = 1,
10297   FieldDescriptorProto_Type_TYPE_FLOAT = 2,
10298   FieldDescriptorProto_Type_TYPE_INT64 = 3,
10299   FieldDescriptorProto_Type_TYPE_UINT64 = 4,
10300   FieldDescriptorProto_Type_TYPE_INT32 = 5,
10301   FieldDescriptorProto_Type_TYPE_FIXED64 = 6,
10302   FieldDescriptorProto_Type_TYPE_FIXED32 = 7,
10303   FieldDescriptorProto_Type_TYPE_BOOL = 8,
10304   FieldDescriptorProto_Type_TYPE_STRING = 9,
10305   FieldDescriptorProto_Type_TYPE_GROUP = 10,
10306   FieldDescriptorProto_Type_TYPE_MESSAGE = 11,
10307   FieldDescriptorProto_Type_TYPE_BYTES = 12,
10308   FieldDescriptorProto_Type_TYPE_UINT32 = 13,
10309   FieldDescriptorProto_Type_TYPE_ENUM = 14,
10310   FieldDescriptorProto_Type_TYPE_SFIXED32 = 15,
10311   FieldDescriptorProto_Type_TYPE_SFIXED64 = 16,
10312   FieldDescriptorProto_Type_TYPE_SINT32 = 17,
10313   FieldDescriptorProto_Type_TYPE_SINT64 = 18,
10314 };
10315 enum FieldDescriptorProto_Label : int {
10316   FieldDescriptorProto_Label_LABEL_OPTIONAL = 1,
10317   FieldDescriptorProto_Label_LABEL_REQUIRED = 2,
10318   FieldDescriptorProto_Label_LABEL_REPEATED = 3,
10319 };
10320 
10321 class PERFETTO_EXPORT OneofOptions : public ::protozero::CppMessageObj {
10322  public:
10323   enum FieldNumbers {
10324   };
10325 
10326   OneofOptions();
10327   ~OneofOptions() override;
10328   OneofOptions(OneofOptions&&) noexcept;
10329   OneofOptions& operator=(OneofOptions&&);
10330   OneofOptions(const OneofOptions&);
10331   OneofOptions& operator=(const OneofOptions&);
10332   bool operator==(const OneofOptions&) const;
operator !=(const OneofOptions & other) const10333   bool operator!=(const OneofOptions& other) const { return !(*this == other); }
10334 
10335   bool ParseFromArray(const void*, size_t) override;
10336   std::string SerializeAsString() const override;
10337   std::vector<uint8_t> SerializeAsArray() const override;
10338   void Serialize(::protozero::Message*) const;
10339 
10340  private:
10341 
10342   // Allows to preserve unknown protobuf fields for compatibility
10343   // with future versions of .proto files.
10344   std::string unknown_fields_;
10345 
10346   std::bitset<2> _has_field_{};
10347 };
10348 
10349 
10350 class PERFETTO_EXPORT EnumValueDescriptorProto : public ::protozero::CppMessageObj {
10351  public:
10352   enum FieldNumbers {
10353     kNameFieldNumber = 1,
10354     kNumberFieldNumber = 2,
10355   };
10356 
10357   EnumValueDescriptorProto();
10358   ~EnumValueDescriptorProto() override;
10359   EnumValueDescriptorProto(EnumValueDescriptorProto&&) noexcept;
10360   EnumValueDescriptorProto& operator=(EnumValueDescriptorProto&&);
10361   EnumValueDescriptorProto(const EnumValueDescriptorProto&);
10362   EnumValueDescriptorProto& operator=(const EnumValueDescriptorProto&);
10363   bool operator==(const EnumValueDescriptorProto&) const;
operator !=(const EnumValueDescriptorProto & other) const10364   bool operator!=(const EnumValueDescriptorProto& other) const { return !(*this == other); }
10365 
10366   bool ParseFromArray(const void*, size_t) override;
10367   std::string SerializeAsString() const override;
10368   std::vector<uint8_t> SerializeAsArray() const override;
10369   void Serialize(::protozero::Message*) const;
10370 
has_name() const10371   bool has_name() const { return _has_field_[1]; }
name() const10372   const std::string& name() const { return name_; }
set_name(const std::string & value)10373   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
10374 
has_number() const10375   bool has_number() const { return _has_field_[2]; }
number() const10376   int32_t number() const { return number_; }
set_number(int32_t value)10377   void set_number(int32_t value) { number_ = value; _has_field_.set(2); }
10378 
10379  private:
10380   std::string name_{};
10381   int32_t number_{};
10382 
10383   // Allows to preserve unknown protobuf fields for compatibility
10384   // with future versions of .proto files.
10385   std::string unknown_fields_;
10386 
10387   std::bitset<3> _has_field_{};
10388 };
10389 
10390 
10391 class PERFETTO_EXPORT EnumDescriptorProto : public ::protozero::CppMessageObj {
10392  public:
10393   enum FieldNumbers {
10394     kNameFieldNumber = 1,
10395     kValueFieldNumber = 2,
10396     kReservedNameFieldNumber = 5,
10397   };
10398 
10399   EnumDescriptorProto();
10400   ~EnumDescriptorProto() override;
10401   EnumDescriptorProto(EnumDescriptorProto&&) noexcept;
10402   EnumDescriptorProto& operator=(EnumDescriptorProto&&);
10403   EnumDescriptorProto(const EnumDescriptorProto&);
10404   EnumDescriptorProto& operator=(const EnumDescriptorProto&);
10405   bool operator==(const EnumDescriptorProto&) const;
operator !=(const EnumDescriptorProto & other) const10406   bool operator!=(const EnumDescriptorProto& other) const { return !(*this == other); }
10407 
10408   bool ParseFromArray(const void*, size_t) override;
10409   std::string SerializeAsString() const override;
10410   std::vector<uint8_t> SerializeAsArray() const override;
10411   void Serialize(::protozero::Message*) const;
10412 
has_name() const10413   bool has_name() const { return _has_field_[1]; }
name() const10414   const std::string& name() const { return name_; }
set_name(const std::string & value)10415   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
10416 
value() const10417   const std::vector<EnumValueDescriptorProto>& value() const { return value_; }
mutable_value()10418   std::vector<EnumValueDescriptorProto>* mutable_value() { return &value_; }
10419   int value_size() const;
10420   void clear_value();
10421   EnumValueDescriptorProto* add_value();
10422 
reserved_name() const10423   const std::vector<std::string>& reserved_name() const { return reserved_name_; }
mutable_reserved_name()10424   std::vector<std::string>* mutable_reserved_name() { return &reserved_name_; }
reserved_name_size() const10425   int reserved_name_size() const { return static_cast<int>(reserved_name_.size()); }
clear_reserved_name()10426   void clear_reserved_name() { reserved_name_.clear(); }
add_reserved_name(std::string value)10427   void add_reserved_name(std::string value) { reserved_name_.emplace_back(value); }
add_reserved_name()10428   std::string* add_reserved_name() { reserved_name_.emplace_back(); return &reserved_name_.back(); }
10429 
10430  private:
10431   std::string name_{};
10432   std::vector<EnumValueDescriptorProto> value_;
10433   std::vector<std::string> reserved_name_;
10434 
10435   // Allows to preserve unknown protobuf fields for compatibility
10436   // with future versions of .proto files.
10437   std::string unknown_fields_;
10438 
10439   std::bitset<6> _has_field_{};
10440 };
10441 
10442 
10443 class PERFETTO_EXPORT OneofDescriptorProto : public ::protozero::CppMessageObj {
10444  public:
10445   enum FieldNumbers {
10446     kNameFieldNumber = 1,
10447     kOptionsFieldNumber = 2,
10448   };
10449 
10450   OneofDescriptorProto();
10451   ~OneofDescriptorProto() override;
10452   OneofDescriptorProto(OneofDescriptorProto&&) noexcept;
10453   OneofDescriptorProto& operator=(OneofDescriptorProto&&);
10454   OneofDescriptorProto(const OneofDescriptorProto&);
10455   OneofDescriptorProto& operator=(const OneofDescriptorProto&);
10456   bool operator==(const OneofDescriptorProto&) const;
operator !=(const OneofDescriptorProto & other) const10457   bool operator!=(const OneofDescriptorProto& other) const { return !(*this == other); }
10458 
10459   bool ParseFromArray(const void*, size_t) override;
10460   std::string SerializeAsString() const override;
10461   std::vector<uint8_t> SerializeAsArray() const override;
10462   void Serialize(::protozero::Message*) const;
10463 
has_name() const10464   bool has_name() const { return _has_field_[1]; }
name() const10465   const std::string& name() const { return name_; }
set_name(const std::string & value)10466   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
10467 
has_options() const10468   bool has_options() const { return _has_field_[2]; }
options() const10469   const OneofOptions& options() const { return *options_; }
mutable_options()10470   OneofOptions* mutable_options() { _has_field_.set(2); return options_.get(); }
10471 
10472  private:
10473   std::string name_{};
10474   ::protozero::CopyablePtr<OneofOptions> options_;
10475 
10476   // Allows to preserve unknown protobuf fields for compatibility
10477   // with future versions of .proto files.
10478   std::string unknown_fields_;
10479 
10480   std::bitset<3> _has_field_{};
10481 };
10482 
10483 
10484 class PERFETTO_EXPORT FieldDescriptorProto : public ::protozero::CppMessageObj {
10485  public:
10486   using Type = FieldDescriptorProto_Type;
10487   static constexpr auto TYPE_DOUBLE = FieldDescriptorProto_Type_TYPE_DOUBLE;
10488   static constexpr auto TYPE_FLOAT = FieldDescriptorProto_Type_TYPE_FLOAT;
10489   static constexpr auto TYPE_INT64 = FieldDescriptorProto_Type_TYPE_INT64;
10490   static constexpr auto TYPE_UINT64 = FieldDescriptorProto_Type_TYPE_UINT64;
10491   static constexpr auto TYPE_INT32 = FieldDescriptorProto_Type_TYPE_INT32;
10492   static constexpr auto TYPE_FIXED64 = FieldDescriptorProto_Type_TYPE_FIXED64;
10493   static constexpr auto TYPE_FIXED32 = FieldDescriptorProto_Type_TYPE_FIXED32;
10494   static constexpr auto TYPE_BOOL = FieldDescriptorProto_Type_TYPE_BOOL;
10495   static constexpr auto TYPE_STRING = FieldDescriptorProto_Type_TYPE_STRING;
10496   static constexpr auto TYPE_GROUP = FieldDescriptorProto_Type_TYPE_GROUP;
10497   static constexpr auto TYPE_MESSAGE = FieldDescriptorProto_Type_TYPE_MESSAGE;
10498   static constexpr auto TYPE_BYTES = FieldDescriptorProto_Type_TYPE_BYTES;
10499   static constexpr auto TYPE_UINT32 = FieldDescriptorProto_Type_TYPE_UINT32;
10500   static constexpr auto TYPE_ENUM = FieldDescriptorProto_Type_TYPE_ENUM;
10501   static constexpr auto TYPE_SFIXED32 = FieldDescriptorProto_Type_TYPE_SFIXED32;
10502   static constexpr auto TYPE_SFIXED64 = FieldDescriptorProto_Type_TYPE_SFIXED64;
10503   static constexpr auto TYPE_SINT32 = FieldDescriptorProto_Type_TYPE_SINT32;
10504   static constexpr auto TYPE_SINT64 = FieldDescriptorProto_Type_TYPE_SINT64;
10505   static constexpr auto Type_MIN = FieldDescriptorProto_Type_TYPE_DOUBLE;
10506   static constexpr auto Type_MAX = FieldDescriptorProto_Type_TYPE_SINT64;
10507   using Label = FieldDescriptorProto_Label;
10508   static constexpr auto LABEL_OPTIONAL = FieldDescriptorProto_Label_LABEL_OPTIONAL;
10509   static constexpr auto LABEL_REQUIRED = FieldDescriptorProto_Label_LABEL_REQUIRED;
10510   static constexpr auto LABEL_REPEATED = FieldDescriptorProto_Label_LABEL_REPEATED;
10511   static constexpr auto Label_MIN = FieldDescriptorProto_Label_LABEL_OPTIONAL;
10512   static constexpr auto Label_MAX = FieldDescriptorProto_Label_LABEL_REPEATED;
10513   enum FieldNumbers {
10514     kNameFieldNumber = 1,
10515     kNumberFieldNumber = 3,
10516     kLabelFieldNumber = 4,
10517     kTypeFieldNumber = 5,
10518     kTypeNameFieldNumber = 6,
10519     kExtendeeFieldNumber = 2,
10520     kDefaultValueFieldNumber = 7,
10521     kOneofIndexFieldNumber = 9,
10522   };
10523 
10524   FieldDescriptorProto();
10525   ~FieldDescriptorProto() override;
10526   FieldDescriptorProto(FieldDescriptorProto&&) noexcept;
10527   FieldDescriptorProto& operator=(FieldDescriptorProto&&);
10528   FieldDescriptorProto(const FieldDescriptorProto&);
10529   FieldDescriptorProto& operator=(const FieldDescriptorProto&);
10530   bool operator==(const FieldDescriptorProto&) const;
operator !=(const FieldDescriptorProto & other) const10531   bool operator!=(const FieldDescriptorProto& other) const { return !(*this == other); }
10532 
10533   bool ParseFromArray(const void*, size_t) override;
10534   std::string SerializeAsString() const override;
10535   std::vector<uint8_t> SerializeAsArray() const override;
10536   void Serialize(::protozero::Message*) const;
10537 
has_name() const10538   bool has_name() const { return _has_field_[1]; }
name() const10539   const std::string& name() const { return name_; }
set_name(const std::string & value)10540   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
10541 
has_number() const10542   bool has_number() const { return _has_field_[3]; }
number() const10543   int32_t number() const { return number_; }
set_number(int32_t value)10544   void set_number(int32_t value) { number_ = value; _has_field_.set(3); }
10545 
has_label() const10546   bool has_label() const { return _has_field_[4]; }
label() const10547   FieldDescriptorProto_Label label() const { return label_; }
set_label(FieldDescriptorProto_Label value)10548   void set_label(FieldDescriptorProto_Label value) { label_ = value; _has_field_.set(4); }
10549 
has_type() const10550   bool has_type() const { return _has_field_[5]; }
type() const10551   FieldDescriptorProto_Type type() const { return type_; }
set_type(FieldDescriptorProto_Type value)10552   void set_type(FieldDescriptorProto_Type value) { type_ = value; _has_field_.set(5); }
10553 
has_type_name() const10554   bool has_type_name() const { return _has_field_[6]; }
type_name() const10555   const std::string& type_name() const { return type_name_; }
set_type_name(const std::string & value)10556   void set_type_name(const std::string& value) { type_name_ = value; _has_field_.set(6); }
10557 
has_extendee() const10558   bool has_extendee() const { return _has_field_[2]; }
extendee() const10559   const std::string& extendee() const { return extendee_; }
set_extendee(const std::string & value)10560   void set_extendee(const std::string& value) { extendee_ = value; _has_field_.set(2); }
10561 
has_default_value() const10562   bool has_default_value() const { return _has_field_[7]; }
default_value() const10563   const std::string& default_value() const { return default_value_; }
set_default_value(const std::string & value)10564   void set_default_value(const std::string& value) { default_value_ = value; _has_field_.set(7); }
10565 
has_oneof_index() const10566   bool has_oneof_index() const { return _has_field_[9]; }
oneof_index() const10567   int32_t oneof_index() const { return oneof_index_; }
set_oneof_index(int32_t value)10568   void set_oneof_index(int32_t value) { oneof_index_ = value; _has_field_.set(9); }
10569 
10570  private:
10571   std::string name_{};
10572   int32_t number_{};
10573   FieldDescriptorProto_Label label_{};
10574   FieldDescriptorProto_Type type_{};
10575   std::string type_name_{};
10576   std::string extendee_{};
10577   std::string default_value_{};
10578   int32_t oneof_index_{};
10579 
10580   // Allows to preserve unknown protobuf fields for compatibility
10581   // with future versions of .proto files.
10582   std::string unknown_fields_;
10583 
10584   std::bitset<10> _has_field_{};
10585 };
10586 
10587 
10588 class PERFETTO_EXPORT DescriptorProto : public ::protozero::CppMessageObj {
10589  public:
10590   using ReservedRange = DescriptorProto_ReservedRange;
10591   enum FieldNumbers {
10592     kNameFieldNumber = 1,
10593     kFieldFieldNumber = 2,
10594     kExtensionFieldNumber = 6,
10595     kNestedTypeFieldNumber = 3,
10596     kEnumTypeFieldNumber = 4,
10597     kOneofDeclFieldNumber = 8,
10598     kReservedRangeFieldNumber = 9,
10599     kReservedNameFieldNumber = 10,
10600   };
10601 
10602   DescriptorProto();
10603   ~DescriptorProto() override;
10604   DescriptorProto(DescriptorProto&&) noexcept;
10605   DescriptorProto& operator=(DescriptorProto&&);
10606   DescriptorProto(const DescriptorProto&);
10607   DescriptorProto& operator=(const DescriptorProto&);
10608   bool operator==(const DescriptorProto&) const;
operator !=(const DescriptorProto & other) const10609   bool operator!=(const DescriptorProto& other) const { return !(*this == other); }
10610 
10611   bool ParseFromArray(const void*, size_t) override;
10612   std::string SerializeAsString() const override;
10613   std::vector<uint8_t> SerializeAsArray() const override;
10614   void Serialize(::protozero::Message*) const;
10615 
has_name() const10616   bool has_name() const { return _has_field_[1]; }
name() const10617   const std::string& name() const { return name_; }
set_name(const std::string & value)10618   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
10619 
field() const10620   const std::vector<FieldDescriptorProto>& field() const { return field_; }
mutable_field()10621   std::vector<FieldDescriptorProto>* mutable_field() { return &field_; }
10622   int field_size() const;
10623   void clear_field();
10624   FieldDescriptorProto* add_field();
10625 
extension() const10626   const std::vector<FieldDescriptorProto>& extension() const { return extension_; }
mutable_extension()10627   std::vector<FieldDescriptorProto>* mutable_extension() { return &extension_; }
10628   int extension_size() const;
10629   void clear_extension();
10630   FieldDescriptorProto* add_extension();
10631 
nested_type() const10632   const std::vector<DescriptorProto>& nested_type() const { return nested_type_; }
mutable_nested_type()10633   std::vector<DescriptorProto>* mutable_nested_type() { return &nested_type_; }
10634   int nested_type_size() const;
10635   void clear_nested_type();
10636   DescriptorProto* add_nested_type();
10637 
enum_type() const10638   const std::vector<EnumDescriptorProto>& enum_type() const { return enum_type_; }
mutable_enum_type()10639   std::vector<EnumDescriptorProto>* mutable_enum_type() { return &enum_type_; }
10640   int enum_type_size() const;
10641   void clear_enum_type();
10642   EnumDescriptorProto* add_enum_type();
10643 
oneof_decl() const10644   const std::vector<OneofDescriptorProto>& oneof_decl() const { return oneof_decl_; }
mutable_oneof_decl()10645   std::vector<OneofDescriptorProto>* mutable_oneof_decl() { return &oneof_decl_; }
10646   int oneof_decl_size() const;
10647   void clear_oneof_decl();
10648   OneofDescriptorProto* add_oneof_decl();
10649 
reserved_range() const10650   const std::vector<DescriptorProto_ReservedRange>& reserved_range() const { return reserved_range_; }
mutable_reserved_range()10651   std::vector<DescriptorProto_ReservedRange>* mutable_reserved_range() { return &reserved_range_; }
10652   int reserved_range_size() const;
10653   void clear_reserved_range();
10654   DescriptorProto_ReservedRange* add_reserved_range();
10655 
reserved_name() const10656   const std::vector<std::string>& reserved_name() const { return reserved_name_; }
mutable_reserved_name()10657   std::vector<std::string>* mutable_reserved_name() { return &reserved_name_; }
reserved_name_size() const10658   int reserved_name_size() const { return static_cast<int>(reserved_name_.size()); }
clear_reserved_name()10659   void clear_reserved_name() { reserved_name_.clear(); }
add_reserved_name(std::string value)10660   void add_reserved_name(std::string value) { reserved_name_.emplace_back(value); }
add_reserved_name()10661   std::string* add_reserved_name() { reserved_name_.emplace_back(); return &reserved_name_.back(); }
10662 
10663  private:
10664   std::string name_{};
10665   std::vector<FieldDescriptorProto> field_;
10666   std::vector<FieldDescriptorProto> extension_;
10667   std::vector<DescriptorProto> nested_type_;
10668   std::vector<EnumDescriptorProto> enum_type_;
10669   std::vector<OneofDescriptorProto> oneof_decl_;
10670   std::vector<DescriptorProto_ReservedRange> reserved_range_;
10671   std::vector<std::string> reserved_name_;
10672 
10673   // Allows to preserve unknown protobuf fields for compatibility
10674   // with future versions of .proto files.
10675   std::string unknown_fields_;
10676 
10677   std::bitset<11> _has_field_{};
10678 };
10679 
10680 
10681 class PERFETTO_EXPORT DescriptorProto_ReservedRange : public ::protozero::CppMessageObj {
10682  public:
10683   enum FieldNumbers {
10684     kStartFieldNumber = 1,
10685     kEndFieldNumber = 2,
10686   };
10687 
10688   DescriptorProto_ReservedRange();
10689   ~DescriptorProto_ReservedRange() override;
10690   DescriptorProto_ReservedRange(DescriptorProto_ReservedRange&&) noexcept;
10691   DescriptorProto_ReservedRange& operator=(DescriptorProto_ReservedRange&&);
10692   DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange&);
10693   DescriptorProto_ReservedRange& operator=(const DescriptorProto_ReservedRange&);
10694   bool operator==(const DescriptorProto_ReservedRange&) const;
operator !=(const DescriptorProto_ReservedRange & other) const10695   bool operator!=(const DescriptorProto_ReservedRange& other) const { return !(*this == other); }
10696 
10697   bool ParseFromArray(const void*, size_t) override;
10698   std::string SerializeAsString() const override;
10699   std::vector<uint8_t> SerializeAsArray() const override;
10700   void Serialize(::protozero::Message*) const;
10701 
has_start() const10702   bool has_start() const { return _has_field_[1]; }
start() const10703   int32_t start() const { return start_; }
set_start(int32_t value)10704   void set_start(int32_t value) { start_ = value; _has_field_.set(1); }
10705 
has_end() const10706   bool has_end() const { return _has_field_[2]; }
end() const10707   int32_t end() const { return end_; }
set_end(int32_t value)10708   void set_end(int32_t value) { end_ = value; _has_field_.set(2); }
10709 
10710  private:
10711   int32_t start_{};
10712   int32_t end_{};
10713 
10714   // Allows to preserve unknown protobuf fields for compatibility
10715   // with future versions of .proto files.
10716   std::string unknown_fields_;
10717 
10718   std::bitset<3> _has_field_{};
10719 };
10720 
10721 
10722 class PERFETTO_EXPORT FileDescriptorProto : public ::protozero::CppMessageObj {
10723  public:
10724   enum FieldNumbers {
10725     kNameFieldNumber = 1,
10726     kPackageFieldNumber = 2,
10727     kDependencyFieldNumber = 3,
10728     kPublicDependencyFieldNumber = 10,
10729     kWeakDependencyFieldNumber = 11,
10730     kMessageTypeFieldNumber = 4,
10731     kEnumTypeFieldNumber = 5,
10732     kExtensionFieldNumber = 7,
10733   };
10734 
10735   FileDescriptorProto();
10736   ~FileDescriptorProto() override;
10737   FileDescriptorProto(FileDescriptorProto&&) noexcept;
10738   FileDescriptorProto& operator=(FileDescriptorProto&&);
10739   FileDescriptorProto(const FileDescriptorProto&);
10740   FileDescriptorProto& operator=(const FileDescriptorProto&);
10741   bool operator==(const FileDescriptorProto&) const;
operator !=(const FileDescriptorProto & other) const10742   bool operator!=(const FileDescriptorProto& other) const { return !(*this == other); }
10743 
10744   bool ParseFromArray(const void*, size_t) override;
10745   std::string SerializeAsString() const override;
10746   std::vector<uint8_t> SerializeAsArray() const override;
10747   void Serialize(::protozero::Message*) const;
10748 
has_name() const10749   bool has_name() const { return _has_field_[1]; }
name() const10750   const std::string& name() const { return name_; }
set_name(const std::string & value)10751   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
10752 
has_package() const10753   bool has_package() const { return _has_field_[2]; }
package() const10754   const std::string& package() const { return package_; }
set_package(const std::string & value)10755   void set_package(const std::string& value) { package_ = value; _has_field_.set(2); }
10756 
dependency() const10757   const std::vector<std::string>& dependency() const { return dependency_; }
mutable_dependency()10758   std::vector<std::string>* mutable_dependency() { return &dependency_; }
dependency_size() const10759   int dependency_size() const { return static_cast<int>(dependency_.size()); }
clear_dependency()10760   void clear_dependency() { dependency_.clear(); }
add_dependency(std::string value)10761   void add_dependency(std::string value) { dependency_.emplace_back(value); }
add_dependency()10762   std::string* add_dependency() { dependency_.emplace_back(); return &dependency_.back(); }
10763 
public_dependency() const10764   const std::vector<int32_t>& public_dependency() const { return public_dependency_; }
mutable_public_dependency()10765   std::vector<int32_t>* mutable_public_dependency() { return &public_dependency_; }
public_dependency_size() const10766   int public_dependency_size() const { return static_cast<int>(public_dependency_.size()); }
clear_public_dependency()10767   void clear_public_dependency() { public_dependency_.clear(); }
add_public_dependency(int32_t value)10768   void add_public_dependency(int32_t value) { public_dependency_.emplace_back(value); }
add_public_dependency()10769   int32_t* add_public_dependency() { public_dependency_.emplace_back(); return &public_dependency_.back(); }
10770 
weak_dependency() const10771   const std::vector<int32_t>& weak_dependency() const { return weak_dependency_; }
mutable_weak_dependency()10772   std::vector<int32_t>* mutable_weak_dependency() { return &weak_dependency_; }
weak_dependency_size() const10773   int weak_dependency_size() const { return static_cast<int>(weak_dependency_.size()); }
clear_weak_dependency()10774   void clear_weak_dependency() { weak_dependency_.clear(); }
add_weak_dependency(int32_t value)10775   void add_weak_dependency(int32_t value) { weak_dependency_.emplace_back(value); }
add_weak_dependency()10776   int32_t* add_weak_dependency() { weak_dependency_.emplace_back(); return &weak_dependency_.back(); }
10777 
message_type() const10778   const std::vector<DescriptorProto>& message_type() const { return message_type_; }
mutable_message_type()10779   std::vector<DescriptorProto>* mutable_message_type() { return &message_type_; }
10780   int message_type_size() const;
10781   void clear_message_type();
10782   DescriptorProto* add_message_type();
10783 
enum_type() const10784   const std::vector<EnumDescriptorProto>& enum_type() const { return enum_type_; }
mutable_enum_type()10785   std::vector<EnumDescriptorProto>* mutable_enum_type() { return &enum_type_; }
10786   int enum_type_size() const;
10787   void clear_enum_type();
10788   EnumDescriptorProto* add_enum_type();
10789 
extension() const10790   const std::vector<FieldDescriptorProto>& extension() const { return extension_; }
mutable_extension()10791   std::vector<FieldDescriptorProto>* mutable_extension() { return &extension_; }
10792   int extension_size() const;
10793   void clear_extension();
10794   FieldDescriptorProto* add_extension();
10795 
10796  private:
10797   std::string name_{};
10798   std::string package_{};
10799   std::vector<std::string> dependency_;
10800   std::vector<int32_t> public_dependency_;
10801   std::vector<int32_t> weak_dependency_;
10802   std::vector<DescriptorProto> message_type_;
10803   std::vector<EnumDescriptorProto> enum_type_;
10804   std::vector<FieldDescriptorProto> extension_;
10805 
10806   // Allows to preserve unknown protobuf fields for compatibility
10807   // with future versions of .proto files.
10808   std::string unknown_fields_;
10809 
10810   std::bitset<12> _has_field_{};
10811 };
10812 
10813 
10814 class PERFETTO_EXPORT FileDescriptorSet : public ::protozero::CppMessageObj {
10815  public:
10816   enum FieldNumbers {
10817     kFileFieldNumber = 1,
10818   };
10819 
10820   FileDescriptorSet();
10821   ~FileDescriptorSet() override;
10822   FileDescriptorSet(FileDescriptorSet&&) noexcept;
10823   FileDescriptorSet& operator=(FileDescriptorSet&&);
10824   FileDescriptorSet(const FileDescriptorSet&);
10825   FileDescriptorSet& operator=(const FileDescriptorSet&);
10826   bool operator==(const FileDescriptorSet&) const;
operator !=(const FileDescriptorSet & other) const10827   bool operator!=(const FileDescriptorSet& other) const { return !(*this == other); }
10828 
10829   bool ParseFromArray(const void*, size_t) override;
10830   std::string SerializeAsString() const override;
10831   std::vector<uint8_t> SerializeAsArray() const override;
10832   void Serialize(::protozero::Message*) const;
10833 
file() const10834   const std::vector<FileDescriptorProto>& file() const { return file_; }
mutable_file()10835   std::vector<FileDescriptorProto>* mutable_file() { return &file_; }
10836   int file_size() const;
10837   void clear_file();
10838   FileDescriptorProto* add_file();
10839 
10840  private:
10841   std::vector<FileDescriptorProto> file_;
10842 
10843   // Allows to preserve unknown protobuf fields for compatibility
10844   // with future versions of .proto files.
10845   std::string unknown_fields_;
10846 
10847   std::bitset<2> _has_field_{};
10848 };
10849 
10850 }  // namespace perfetto
10851 }  // namespace protos
10852 }  // namespace gen
10853 
10854 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DESCRIPTOR_PROTO_CPP_H_
10855 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
10856 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
10857 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
10858 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
10859 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
10860 #if defined(__GNUC__) || defined(__clang__)
10861 #pragma GCC diagnostic push
10862 #pragma GCC diagnostic ignored "-Wfloat-equal"
10863 #endif
10864 // gen_amalgamated expanded: #include "protos/perfetto/common/descriptor.gen.h"
10865 
10866 namespace perfetto {
10867 namespace protos {
10868 namespace gen {
10869 
10870 OneofOptions::OneofOptions() = default;
10871 OneofOptions::~OneofOptions() = default;
10872 OneofOptions::OneofOptions(const OneofOptions&) = default;
10873 OneofOptions& OneofOptions::operator=(const OneofOptions&) = default;
10874 OneofOptions::OneofOptions(OneofOptions&&) noexcept = default;
10875 OneofOptions& OneofOptions::operator=(OneofOptions&&) = default;
10876 
operator ==(const OneofOptions & other) const10877 bool OneofOptions::operator==(const OneofOptions& other) const {
10878   return unknown_fields_ == other.unknown_fields_;
10879 }
10880 
ParseFromArray(const void * raw,size_t size)10881 bool OneofOptions::ParseFromArray(const void* raw, size_t size) {
10882   unknown_fields_.clear();
10883   bool packed_error = false;
10884 
10885   ::protozero::ProtoDecoder dec(raw, size);
10886   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
10887     if (field.id() < _has_field_.size()) {
10888       _has_field_.set(field.id());
10889     }
10890     switch (field.id()) {
10891       default:
10892         field.SerializeAndAppendTo(&unknown_fields_);
10893         break;
10894     }
10895   }
10896   return !packed_error && !dec.bytes_left();
10897 }
10898 
SerializeAsString() const10899 std::string OneofOptions::SerializeAsString() const {
10900   ::protozero::HeapBuffered<::protozero::Message> msg;
10901   Serialize(msg.get());
10902   return msg.SerializeAsString();
10903 }
10904 
SerializeAsArray() const10905 std::vector<uint8_t> OneofOptions::SerializeAsArray() const {
10906   ::protozero::HeapBuffered<::protozero::Message> msg;
10907   Serialize(msg.get());
10908   return msg.SerializeAsArray();
10909 }
10910 
Serialize(::protozero::Message * msg) const10911 void OneofOptions::Serialize(::protozero::Message* msg) const {
10912   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
10913 }
10914 
10915 
10916 EnumValueDescriptorProto::EnumValueDescriptorProto() = default;
10917 EnumValueDescriptorProto::~EnumValueDescriptorProto() = default;
10918 EnumValueDescriptorProto::EnumValueDescriptorProto(const EnumValueDescriptorProto&) = default;
10919 EnumValueDescriptorProto& EnumValueDescriptorProto::operator=(const EnumValueDescriptorProto&) = default;
10920 EnumValueDescriptorProto::EnumValueDescriptorProto(EnumValueDescriptorProto&&) noexcept = default;
10921 EnumValueDescriptorProto& EnumValueDescriptorProto::operator=(EnumValueDescriptorProto&&) = default;
10922 
operator ==(const EnumValueDescriptorProto & other) const10923 bool EnumValueDescriptorProto::operator==(const EnumValueDescriptorProto& other) const {
10924   return unknown_fields_ == other.unknown_fields_
10925    && name_ == other.name_
10926    && number_ == other.number_;
10927 }
10928 
ParseFromArray(const void * raw,size_t size)10929 bool EnumValueDescriptorProto::ParseFromArray(const void* raw, size_t size) {
10930   unknown_fields_.clear();
10931   bool packed_error = false;
10932 
10933   ::protozero::ProtoDecoder dec(raw, size);
10934   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
10935     if (field.id() < _has_field_.size()) {
10936       _has_field_.set(field.id());
10937     }
10938     switch (field.id()) {
10939       case 1 /* name */:
10940         field.get(&name_);
10941         break;
10942       case 2 /* number */:
10943         field.get(&number_);
10944         break;
10945       default:
10946         field.SerializeAndAppendTo(&unknown_fields_);
10947         break;
10948     }
10949   }
10950   return !packed_error && !dec.bytes_left();
10951 }
10952 
SerializeAsString() const10953 std::string EnumValueDescriptorProto::SerializeAsString() const {
10954   ::protozero::HeapBuffered<::protozero::Message> msg;
10955   Serialize(msg.get());
10956   return msg.SerializeAsString();
10957 }
10958 
SerializeAsArray() const10959 std::vector<uint8_t> EnumValueDescriptorProto::SerializeAsArray() const {
10960   ::protozero::HeapBuffered<::protozero::Message> msg;
10961   Serialize(msg.get());
10962   return msg.SerializeAsArray();
10963 }
10964 
Serialize(::protozero::Message * msg) const10965 void EnumValueDescriptorProto::Serialize(::protozero::Message* msg) const {
10966   // Field 1: name
10967   if (_has_field_[1]) {
10968     msg->AppendString(1, name_);
10969   }
10970 
10971   // Field 2: number
10972   if (_has_field_[2]) {
10973     msg->AppendVarInt(2, number_);
10974   }
10975 
10976   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
10977 }
10978 
10979 
10980 EnumDescriptorProto::EnumDescriptorProto() = default;
10981 EnumDescriptorProto::~EnumDescriptorProto() = default;
10982 EnumDescriptorProto::EnumDescriptorProto(const EnumDescriptorProto&) = default;
10983 EnumDescriptorProto& EnumDescriptorProto::operator=(const EnumDescriptorProto&) = default;
10984 EnumDescriptorProto::EnumDescriptorProto(EnumDescriptorProto&&) noexcept = default;
10985 EnumDescriptorProto& EnumDescriptorProto::operator=(EnumDescriptorProto&&) = default;
10986 
operator ==(const EnumDescriptorProto & other) const10987 bool EnumDescriptorProto::operator==(const EnumDescriptorProto& other) const {
10988   return unknown_fields_ == other.unknown_fields_
10989    && name_ == other.name_
10990    && value_ == other.value_
10991    && reserved_name_ == other.reserved_name_;
10992 }
10993 
value_size() const10994 int EnumDescriptorProto::value_size() const { return static_cast<int>(value_.size()); }
clear_value()10995 void EnumDescriptorProto::clear_value() { value_.clear(); }
add_value()10996 EnumValueDescriptorProto* EnumDescriptorProto::add_value() { value_.emplace_back(); return &value_.back(); }
ParseFromArray(const void * raw,size_t size)10997 bool EnumDescriptorProto::ParseFromArray(const void* raw, size_t size) {
10998   value_.clear();
10999   reserved_name_.clear();
11000   unknown_fields_.clear();
11001   bool packed_error = false;
11002 
11003   ::protozero::ProtoDecoder dec(raw, size);
11004   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
11005     if (field.id() < _has_field_.size()) {
11006       _has_field_.set(field.id());
11007     }
11008     switch (field.id()) {
11009       case 1 /* name */:
11010         field.get(&name_);
11011         break;
11012       case 2 /* value */:
11013         value_.emplace_back();
11014         value_.back().ParseFromArray(field.data(), field.size());
11015         break;
11016       case 5 /* reserved_name */:
11017         reserved_name_.emplace_back();
11018         field.get(&reserved_name_.back());
11019         break;
11020       default:
11021         field.SerializeAndAppendTo(&unknown_fields_);
11022         break;
11023     }
11024   }
11025   return !packed_error && !dec.bytes_left();
11026 }
11027 
SerializeAsString() const11028 std::string EnumDescriptorProto::SerializeAsString() const {
11029   ::protozero::HeapBuffered<::protozero::Message> msg;
11030   Serialize(msg.get());
11031   return msg.SerializeAsString();
11032 }
11033 
SerializeAsArray() const11034 std::vector<uint8_t> EnumDescriptorProto::SerializeAsArray() const {
11035   ::protozero::HeapBuffered<::protozero::Message> msg;
11036   Serialize(msg.get());
11037   return msg.SerializeAsArray();
11038 }
11039 
Serialize(::protozero::Message * msg) const11040 void EnumDescriptorProto::Serialize(::protozero::Message* msg) const {
11041   // Field 1: name
11042   if (_has_field_[1]) {
11043     msg->AppendString(1, name_);
11044   }
11045 
11046   // Field 2: value
11047   for (auto& it : value_) {
11048     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
11049   }
11050 
11051   // Field 5: reserved_name
11052   for (auto& it : reserved_name_) {
11053     msg->AppendString(5, it);
11054   }
11055 
11056   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
11057 }
11058 
11059 
11060 OneofDescriptorProto::OneofDescriptorProto() = default;
11061 OneofDescriptorProto::~OneofDescriptorProto() = default;
11062 OneofDescriptorProto::OneofDescriptorProto(const OneofDescriptorProto&) = default;
11063 OneofDescriptorProto& OneofDescriptorProto::operator=(const OneofDescriptorProto&) = default;
11064 OneofDescriptorProto::OneofDescriptorProto(OneofDescriptorProto&&) noexcept = default;
11065 OneofDescriptorProto& OneofDescriptorProto::operator=(OneofDescriptorProto&&) = default;
11066 
operator ==(const OneofDescriptorProto & other) const11067 bool OneofDescriptorProto::operator==(const OneofDescriptorProto& other) const {
11068   return unknown_fields_ == other.unknown_fields_
11069    && name_ == other.name_
11070    && options_ == other.options_;
11071 }
11072 
ParseFromArray(const void * raw,size_t size)11073 bool OneofDescriptorProto::ParseFromArray(const void* raw, size_t size) {
11074   unknown_fields_.clear();
11075   bool packed_error = false;
11076 
11077   ::protozero::ProtoDecoder dec(raw, size);
11078   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
11079     if (field.id() < _has_field_.size()) {
11080       _has_field_.set(field.id());
11081     }
11082     switch (field.id()) {
11083       case 1 /* name */:
11084         field.get(&name_);
11085         break;
11086       case 2 /* options */:
11087         (*options_).ParseFromArray(field.data(), field.size());
11088         break;
11089       default:
11090         field.SerializeAndAppendTo(&unknown_fields_);
11091         break;
11092     }
11093   }
11094   return !packed_error && !dec.bytes_left();
11095 }
11096 
SerializeAsString() const11097 std::string OneofDescriptorProto::SerializeAsString() const {
11098   ::protozero::HeapBuffered<::protozero::Message> msg;
11099   Serialize(msg.get());
11100   return msg.SerializeAsString();
11101 }
11102 
SerializeAsArray() const11103 std::vector<uint8_t> OneofDescriptorProto::SerializeAsArray() const {
11104   ::protozero::HeapBuffered<::protozero::Message> msg;
11105   Serialize(msg.get());
11106   return msg.SerializeAsArray();
11107 }
11108 
Serialize(::protozero::Message * msg) const11109 void OneofDescriptorProto::Serialize(::protozero::Message* msg) const {
11110   // Field 1: name
11111   if (_has_field_[1]) {
11112     msg->AppendString(1, name_);
11113   }
11114 
11115   // Field 2: options
11116   if (_has_field_[2]) {
11117     (*options_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
11118   }
11119 
11120   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
11121 }
11122 
11123 
11124 FieldDescriptorProto::FieldDescriptorProto() = default;
11125 FieldDescriptorProto::~FieldDescriptorProto() = default;
11126 FieldDescriptorProto::FieldDescriptorProto(const FieldDescriptorProto&) = default;
11127 FieldDescriptorProto& FieldDescriptorProto::operator=(const FieldDescriptorProto&) = default;
11128 FieldDescriptorProto::FieldDescriptorProto(FieldDescriptorProto&&) noexcept = default;
11129 FieldDescriptorProto& FieldDescriptorProto::operator=(FieldDescriptorProto&&) = default;
11130 
operator ==(const FieldDescriptorProto & other) const11131 bool FieldDescriptorProto::operator==(const FieldDescriptorProto& other) const {
11132   return unknown_fields_ == other.unknown_fields_
11133    && name_ == other.name_
11134    && number_ == other.number_
11135    && label_ == other.label_
11136    && type_ == other.type_
11137    && type_name_ == other.type_name_
11138    && extendee_ == other.extendee_
11139    && default_value_ == other.default_value_
11140    && oneof_index_ == other.oneof_index_;
11141 }
11142 
ParseFromArray(const void * raw,size_t size)11143 bool FieldDescriptorProto::ParseFromArray(const void* raw, size_t size) {
11144   unknown_fields_.clear();
11145   bool packed_error = false;
11146 
11147   ::protozero::ProtoDecoder dec(raw, size);
11148   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
11149     if (field.id() < _has_field_.size()) {
11150       _has_field_.set(field.id());
11151     }
11152     switch (field.id()) {
11153       case 1 /* name */:
11154         field.get(&name_);
11155         break;
11156       case 3 /* number */:
11157         field.get(&number_);
11158         break;
11159       case 4 /* label */:
11160         field.get(&label_);
11161         break;
11162       case 5 /* type */:
11163         field.get(&type_);
11164         break;
11165       case 6 /* type_name */:
11166         field.get(&type_name_);
11167         break;
11168       case 2 /* extendee */:
11169         field.get(&extendee_);
11170         break;
11171       case 7 /* default_value */:
11172         field.get(&default_value_);
11173         break;
11174       case 9 /* oneof_index */:
11175         field.get(&oneof_index_);
11176         break;
11177       default:
11178         field.SerializeAndAppendTo(&unknown_fields_);
11179         break;
11180     }
11181   }
11182   return !packed_error && !dec.bytes_left();
11183 }
11184 
SerializeAsString() const11185 std::string FieldDescriptorProto::SerializeAsString() const {
11186   ::protozero::HeapBuffered<::protozero::Message> msg;
11187   Serialize(msg.get());
11188   return msg.SerializeAsString();
11189 }
11190 
SerializeAsArray() const11191 std::vector<uint8_t> FieldDescriptorProto::SerializeAsArray() const {
11192   ::protozero::HeapBuffered<::protozero::Message> msg;
11193   Serialize(msg.get());
11194   return msg.SerializeAsArray();
11195 }
11196 
Serialize(::protozero::Message * msg) const11197 void FieldDescriptorProto::Serialize(::protozero::Message* msg) const {
11198   // Field 1: name
11199   if (_has_field_[1]) {
11200     msg->AppendString(1, name_);
11201   }
11202 
11203   // Field 3: number
11204   if (_has_field_[3]) {
11205     msg->AppendVarInt(3, number_);
11206   }
11207 
11208   // Field 4: label
11209   if (_has_field_[4]) {
11210     msg->AppendVarInt(4, label_);
11211   }
11212 
11213   // Field 5: type
11214   if (_has_field_[5]) {
11215     msg->AppendVarInt(5, type_);
11216   }
11217 
11218   // Field 6: type_name
11219   if (_has_field_[6]) {
11220     msg->AppendString(6, type_name_);
11221   }
11222 
11223   // Field 2: extendee
11224   if (_has_field_[2]) {
11225     msg->AppendString(2, extendee_);
11226   }
11227 
11228   // Field 7: default_value
11229   if (_has_field_[7]) {
11230     msg->AppendString(7, default_value_);
11231   }
11232 
11233   // Field 9: oneof_index
11234   if (_has_field_[9]) {
11235     msg->AppendVarInt(9, oneof_index_);
11236   }
11237 
11238   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
11239 }
11240 
11241 
11242 DescriptorProto::DescriptorProto() = default;
11243 DescriptorProto::~DescriptorProto() = default;
11244 DescriptorProto::DescriptorProto(const DescriptorProto&) = default;
11245 DescriptorProto& DescriptorProto::operator=(const DescriptorProto&) = default;
11246 DescriptorProto::DescriptorProto(DescriptorProto&&) noexcept = default;
11247 DescriptorProto& DescriptorProto::operator=(DescriptorProto&&) = default;
11248 
operator ==(const DescriptorProto & other) const11249 bool DescriptorProto::operator==(const DescriptorProto& other) const {
11250   return unknown_fields_ == other.unknown_fields_
11251    && name_ == other.name_
11252    && field_ == other.field_
11253    && extension_ == other.extension_
11254    && nested_type_ == other.nested_type_
11255    && enum_type_ == other.enum_type_
11256    && oneof_decl_ == other.oneof_decl_
11257    && reserved_range_ == other.reserved_range_
11258    && reserved_name_ == other.reserved_name_;
11259 }
11260 
field_size() const11261 int DescriptorProto::field_size() const { return static_cast<int>(field_.size()); }
clear_field()11262 void DescriptorProto::clear_field() { field_.clear(); }
add_field()11263 FieldDescriptorProto* DescriptorProto::add_field() { field_.emplace_back(); return &field_.back(); }
extension_size() const11264 int DescriptorProto::extension_size() const { return static_cast<int>(extension_.size()); }
clear_extension()11265 void DescriptorProto::clear_extension() { extension_.clear(); }
add_extension()11266 FieldDescriptorProto* DescriptorProto::add_extension() { extension_.emplace_back(); return &extension_.back(); }
nested_type_size() const11267 int DescriptorProto::nested_type_size() const { return static_cast<int>(nested_type_.size()); }
clear_nested_type()11268 void DescriptorProto::clear_nested_type() { nested_type_.clear(); }
add_nested_type()11269 DescriptorProto* DescriptorProto::add_nested_type() { nested_type_.emplace_back(); return &nested_type_.back(); }
enum_type_size() const11270 int DescriptorProto::enum_type_size() const { return static_cast<int>(enum_type_.size()); }
clear_enum_type()11271 void DescriptorProto::clear_enum_type() { enum_type_.clear(); }
add_enum_type()11272 EnumDescriptorProto* DescriptorProto::add_enum_type() { enum_type_.emplace_back(); return &enum_type_.back(); }
oneof_decl_size() const11273 int DescriptorProto::oneof_decl_size() const { return static_cast<int>(oneof_decl_.size()); }
clear_oneof_decl()11274 void DescriptorProto::clear_oneof_decl() { oneof_decl_.clear(); }
add_oneof_decl()11275 OneofDescriptorProto* DescriptorProto::add_oneof_decl() { oneof_decl_.emplace_back(); return &oneof_decl_.back(); }
reserved_range_size() const11276 int DescriptorProto::reserved_range_size() const { return static_cast<int>(reserved_range_.size()); }
clear_reserved_range()11277 void DescriptorProto::clear_reserved_range() { reserved_range_.clear(); }
add_reserved_range()11278 DescriptorProto_ReservedRange* DescriptorProto::add_reserved_range() { reserved_range_.emplace_back(); return &reserved_range_.back(); }
ParseFromArray(const void * raw,size_t size)11279 bool DescriptorProto::ParseFromArray(const void* raw, size_t size) {
11280   field_.clear();
11281   extension_.clear();
11282   nested_type_.clear();
11283   enum_type_.clear();
11284   oneof_decl_.clear();
11285   reserved_range_.clear();
11286   reserved_name_.clear();
11287   unknown_fields_.clear();
11288   bool packed_error = false;
11289 
11290   ::protozero::ProtoDecoder dec(raw, size);
11291   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
11292     if (field.id() < _has_field_.size()) {
11293       _has_field_.set(field.id());
11294     }
11295     switch (field.id()) {
11296       case 1 /* name */:
11297         field.get(&name_);
11298         break;
11299       case 2 /* field */:
11300         field_.emplace_back();
11301         field_.back().ParseFromArray(field.data(), field.size());
11302         break;
11303       case 6 /* extension */:
11304         extension_.emplace_back();
11305         extension_.back().ParseFromArray(field.data(), field.size());
11306         break;
11307       case 3 /* nested_type */:
11308         nested_type_.emplace_back();
11309         nested_type_.back().ParseFromArray(field.data(), field.size());
11310         break;
11311       case 4 /* enum_type */:
11312         enum_type_.emplace_back();
11313         enum_type_.back().ParseFromArray(field.data(), field.size());
11314         break;
11315       case 8 /* oneof_decl */:
11316         oneof_decl_.emplace_back();
11317         oneof_decl_.back().ParseFromArray(field.data(), field.size());
11318         break;
11319       case 9 /* reserved_range */:
11320         reserved_range_.emplace_back();
11321         reserved_range_.back().ParseFromArray(field.data(), field.size());
11322         break;
11323       case 10 /* reserved_name */:
11324         reserved_name_.emplace_back();
11325         field.get(&reserved_name_.back());
11326         break;
11327       default:
11328         field.SerializeAndAppendTo(&unknown_fields_);
11329         break;
11330     }
11331   }
11332   return !packed_error && !dec.bytes_left();
11333 }
11334 
SerializeAsString() const11335 std::string DescriptorProto::SerializeAsString() const {
11336   ::protozero::HeapBuffered<::protozero::Message> msg;
11337   Serialize(msg.get());
11338   return msg.SerializeAsString();
11339 }
11340 
SerializeAsArray() const11341 std::vector<uint8_t> DescriptorProto::SerializeAsArray() const {
11342   ::protozero::HeapBuffered<::protozero::Message> msg;
11343   Serialize(msg.get());
11344   return msg.SerializeAsArray();
11345 }
11346 
Serialize(::protozero::Message * msg) const11347 void DescriptorProto::Serialize(::protozero::Message* msg) const {
11348   // Field 1: name
11349   if (_has_field_[1]) {
11350     msg->AppendString(1, name_);
11351   }
11352 
11353   // Field 2: field
11354   for (auto& it : field_) {
11355     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
11356   }
11357 
11358   // Field 6: extension
11359   for (auto& it : extension_) {
11360     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
11361   }
11362 
11363   // Field 3: nested_type
11364   for (auto& it : nested_type_) {
11365     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
11366   }
11367 
11368   // Field 4: enum_type
11369   for (auto& it : enum_type_) {
11370     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
11371   }
11372 
11373   // Field 8: oneof_decl
11374   for (auto& it : oneof_decl_) {
11375     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(8));
11376   }
11377 
11378   // Field 9: reserved_range
11379   for (auto& it : reserved_range_) {
11380     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(9));
11381   }
11382 
11383   // Field 10: reserved_name
11384   for (auto& it : reserved_name_) {
11385     msg->AppendString(10, it);
11386   }
11387 
11388   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
11389 }
11390 
11391 
11392 DescriptorProto_ReservedRange::DescriptorProto_ReservedRange() = default;
11393 DescriptorProto_ReservedRange::~DescriptorProto_ReservedRange() = default;
11394 DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange&) = default;
11395 DescriptorProto_ReservedRange& DescriptorProto_ReservedRange::operator=(const DescriptorProto_ReservedRange&) = default;
11396 DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(DescriptorProto_ReservedRange&&) noexcept = default;
11397 DescriptorProto_ReservedRange& DescriptorProto_ReservedRange::operator=(DescriptorProto_ReservedRange&&) = default;
11398 
operator ==(const DescriptorProto_ReservedRange & other) const11399 bool DescriptorProto_ReservedRange::operator==(const DescriptorProto_ReservedRange& other) const {
11400   return unknown_fields_ == other.unknown_fields_
11401    && start_ == other.start_
11402    && end_ == other.end_;
11403 }
11404 
ParseFromArray(const void * raw,size_t size)11405 bool DescriptorProto_ReservedRange::ParseFromArray(const void* raw, size_t size) {
11406   unknown_fields_.clear();
11407   bool packed_error = false;
11408 
11409   ::protozero::ProtoDecoder dec(raw, size);
11410   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
11411     if (field.id() < _has_field_.size()) {
11412       _has_field_.set(field.id());
11413     }
11414     switch (field.id()) {
11415       case 1 /* start */:
11416         field.get(&start_);
11417         break;
11418       case 2 /* end */:
11419         field.get(&end_);
11420         break;
11421       default:
11422         field.SerializeAndAppendTo(&unknown_fields_);
11423         break;
11424     }
11425   }
11426   return !packed_error && !dec.bytes_left();
11427 }
11428 
SerializeAsString() const11429 std::string DescriptorProto_ReservedRange::SerializeAsString() const {
11430   ::protozero::HeapBuffered<::protozero::Message> msg;
11431   Serialize(msg.get());
11432   return msg.SerializeAsString();
11433 }
11434 
SerializeAsArray() const11435 std::vector<uint8_t> DescriptorProto_ReservedRange::SerializeAsArray() const {
11436   ::protozero::HeapBuffered<::protozero::Message> msg;
11437   Serialize(msg.get());
11438   return msg.SerializeAsArray();
11439 }
11440 
Serialize(::protozero::Message * msg) const11441 void DescriptorProto_ReservedRange::Serialize(::protozero::Message* msg) const {
11442   // Field 1: start
11443   if (_has_field_[1]) {
11444     msg->AppendVarInt(1, start_);
11445   }
11446 
11447   // Field 2: end
11448   if (_has_field_[2]) {
11449     msg->AppendVarInt(2, end_);
11450   }
11451 
11452   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
11453 }
11454 
11455 
11456 FileDescriptorProto::FileDescriptorProto() = default;
11457 FileDescriptorProto::~FileDescriptorProto() = default;
11458 FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto&) = default;
11459 FileDescriptorProto& FileDescriptorProto::operator=(const FileDescriptorProto&) = default;
11460 FileDescriptorProto::FileDescriptorProto(FileDescriptorProto&&) noexcept = default;
11461 FileDescriptorProto& FileDescriptorProto::operator=(FileDescriptorProto&&) = default;
11462 
operator ==(const FileDescriptorProto & other) const11463 bool FileDescriptorProto::operator==(const FileDescriptorProto& other) const {
11464   return unknown_fields_ == other.unknown_fields_
11465    && name_ == other.name_
11466    && package_ == other.package_
11467    && dependency_ == other.dependency_
11468    && public_dependency_ == other.public_dependency_
11469    && weak_dependency_ == other.weak_dependency_
11470    && message_type_ == other.message_type_
11471    && enum_type_ == other.enum_type_
11472    && extension_ == other.extension_;
11473 }
11474 
message_type_size() const11475 int FileDescriptorProto::message_type_size() const { return static_cast<int>(message_type_.size()); }
clear_message_type()11476 void FileDescriptorProto::clear_message_type() { message_type_.clear(); }
add_message_type()11477 DescriptorProto* FileDescriptorProto::add_message_type() { message_type_.emplace_back(); return &message_type_.back(); }
enum_type_size() const11478 int FileDescriptorProto::enum_type_size() const { return static_cast<int>(enum_type_.size()); }
clear_enum_type()11479 void FileDescriptorProto::clear_enum_type() { enum_type_.clear(); }
add_enum_type()11480 EnumDescriptorProto* FileDescriptorProto::add_enum_type() { enum_type_.emplace_back(); return &enum_type_.back(); }
extension_size() const11481 int FileDescriptorProto::extension_size() const { return static_cast<int>(extension_.size()); }
clear_extension()11482 void FileDescriptorProto::clear_extension() { extension_.clear(); }
add_extension()11483 FieldDescriptorProto* FileDescriptorProto::add_extension() { extension_.emplace_back(); return &extension_.back(); }
ParseFromArray(const void * raw,size_t size)11484 bool FileDescriptorProto::ParseFromArray(const void* raw, size_t size) {
11485   dependency_.clear();
11486   public_dependency_.clear();
11487   weak_dependency_.clear();
11488   message_type_.clear();
11489   enum_type_.clear();
11490   extension_.clear();
11491   unknown_fields_.clear();
11492   bool packed_error = false;
11493 
11494   ::protozero::ProtoDecoder dec(raw, size);
11495   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
11496     if (field.id() < _has_field_.size()) {
11497       _has_field_.set(field.id());
11498     }
11499     switch (field.id()) {
11500       case 1 /* name */:
11501         field.get(&name_);
11502         break;
11503       case 2 /* package */:
11504         field.get(&package_);
11505         break;
11506       case 3 /* dependency */:
11507         dependency_.emplace_back();
11508         field.get(&dependency_.back());
11509         break;
11510       case 10 /* public_dependency */:
11511         public_dependency_.emplace_back();
11512         field.get(&public_dependency_.back());
11513         break;
11514       case 11 /* weak_dependency */:
11515         weak_dependency_.emplace_back();
11516         field.get(&weak_dependency_.back());
11517         break;
11518       case 4 /* message_type */:
11519         message_type_.emplace_back();
11520         message_type_.back().ParseFromArray(field.data(), field.size());
11521         break;
11522       case 5 /* enum_type */:
11523         enum_type_.emplace_back();
11524         enum_type_.back().ParseFromArray(field.data(), field.size());
11525         break;
11526       case 7 /* extension */:
11527         extension_.emplace_back();
11528         extension_.back().ParseFromArray(field.data(), field.size());
11529         break;
11530       default:
11531         field.SerializeAndAppendTo(&unknown_fields_);
11532         break;
11533     }
11534   }
11535   return !packed_error && !dec.bytes_left();
11536 }
11537 
SerializeAsString() const11538 std::string FileDescriptorProto::SerializeAsString() const {
11539   ::protozero::HeapBuffered<::protozero::Message> msg;
11540   Serialize(msg.get());
11541   return msg.SerializeAsString();
11542 }
11543 
SerializeAsArray() const11544 std::vector<uint8_t> FileDescriptorProto::SerializeAsArray() const {
11545   ::protozero::HeapBuffered<::protozero::Message> msg;
11546   Serialize(msg.get());
11547   return msg.SerializeAsArray();
11548 }
11549 
Serialize(::protozero::Message * msg) const11550 void FileDescriptorProto::Serialize(::protozero::Message* msg) const {
11551   // Field 1: name
11552   if (_has_field_[1]) {
11553     msg->AppendString(1, name_);
11554   }
11555 
11556   // Field 2: package
11557   if (_has_field_[2]) {
11558     msg->AppendString(2, package_);
11559   }
11560 
11561   // Field 3: dependency
11562   for (auto& it : dependency_) {
11563     msg->AppendString(3, it);
11564   }
11565 
11566   // Field 10: public_dependency
11567   for (auto& it : public_dependency_) {
11568     msg->AppendVarInt(10, it);
11569   }
11570 
11571   // Field 11: weak_dependency
11572   for (auto& it : weak_dependency_) {
11573     msg->AppendVarInt(11, it);
11574   }
11575 
11576   // Field 4: message_type
11577   for (auto& it : message_type_) {
11578     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
11579   }
11580 
11581   // Field 5: enum_type
11582   for (auto& it : enum_type_) {
11583     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
11584   }
11585 
11586   // Field 7: extension
11587   for (auto& it : extension_) {
11588     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
11589   }
11590 
11591   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
11592 }
11593 
11594 
11595 FileDescriptorSet::FileDescriptorSet() = default;
11596 FileDescriptorSet::~FileDescriptorSet() = default;
11597 FileDescriptorSet::FileDescriptorSet(const FileDescriptorSet&) = default;
11598 FileDescriptorSet& FileDescriptorSet::operator=(const FileDescriptorSet&) = default;
11599 FileDescriptorSet::FileDescriptorSet(FileDescriptorSet&&) noexcept = default;
11600 FileDescriptorSet& FileDescriptorSet::operator=(FileDescriptorSet&&) = default;
11601 
operator ==(const FileDescriptorSet & other) const11602 bool FileDescriptorSet::operator==(const FileDescriptorSet& other) const {
11603   return unknown_fields_ == other.unknown_fields_
11604    && file_ == other.file_;
11605 }
11606 
file_size() const11607 int FileDescriptorSet::file_size() const { return static_cast<int>(file_.size()); }
clear_file()11608 void FileDescriptorSet::clear_file() { file_.clear(); }
add_file()11609 FileDescriptorProto* FileDescriptorSet::add_file() { file_.emplace_back(); return &file_.back(); }
ParseFromArray(const void * raw,size_t size)11610 bool FileDescriptorSet::ParseFromArray(const void* raw, size_t size) {
11611   file_.clear();
11612   unknown_fields_.clear();
11613   bool packed_error = false;
11614 
11615   ::protozero::ProtoDecoder dec(raw, size);
11616   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
11617     if (field.id() < _has_field_.size()) {
11618       _has_field_.set(field.id());
11619     }
11620     switch (field.id()) {
11621       case 1 /* file */:
11622         file_.emplace_back();
11623         file_.back().ParseFromArray(field.data(), field.size());
11624         break;
11625       default:
11626         field.SerializeAndAppendTo(&unknown_fields_);
11627         break;
11628     }
11629   }
11630   return !packed_error && !dec.bytes_left();
11631 }
11632 
SerializeAsString() const11633 std::string FileDescriptorSet::SerializeAsString() const {
11634   ::protozero::HeapBuffered<::protozero::Message> msg;
11635   Serialize(msg.get());
11636   return msg.SerializeAsString();
11637 }
11638 
SerializeAsArray() const11639 std::vector<uint8_t> FileDescriptorSet::SerializeAsArray() const {
11640   ::protozero::HeapBuffered<::protozero::Message> msg;
11641   Serialize(msg.get());
11642   return msg.SerializeAsArray();
11643 }
11644 
Serialize(::protozero::Message * msg) const11645 void FileDescriptorSet::Serialize(::protozero::Message* msg) const {
11646   // Field 1: file
11647   for (auto& it : file_) {
11648     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
11649   }
11650 
11651   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
11652 }
11653 
11654 }  // namespace perfetto
11655 }  // namespace protos
11656 }  // namespace gen
11657 #if defined(__GNUC__) || defined(__clang__)
11658 #pragma GCC diagnostic pop
11659 #endif
11660 // gen_amalgamated begin source: gen/protos/perfetto/common/gpu_counter_descriptor.gen.cc
11661 // gen_amalgamated begin header: gen/protos/perfetto/common/gpu_counter_descriptor.gen.h
11662 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
11663 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_GPU_COUNTER_DESCRIPTOR_PROTO_CPP_H_
11664 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_GPU_COUNTER_DESCRIPTOR_PROTO_CPP_H_
11665 
11666 #include <stdint.h>
11667 #include <bitset>
11668 #include <vector>
11669 #include <string>
11670 #include <type_traits>
11671 
11672 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
11673 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
11674 // gen_amalgamated expanded: #include "perfetto/base/export.h"
11675 
11676 namespace perfetto {
11677 namespace protos {
11678 namespace gen {
11679 class GpuCounterDescriptor;
11680 class GpuCounterDescriptor_GpuCounterBlock;
11681 class GpuCounterDescriptor_GpuCounterSpec;
11682 enum GpuCounterDescriptor_GpuCounterGroup : int;
11683 enum GpuCounterDescriptor_MeasureUnit : int;
11684 }  // namespace perfetto
11685 }  // namespace protos
11686 }  // namespace gen
11687 
11688 namespace protozero {
11689 class Message;
11690 }  // namespace protozero
11691 
11692 namespace perfetto {
11693 namespace protos {
11694 namespace gen {
11695 enum GpuCounterDescriptor_GpuCounterGroup : int {
11696   GpuCounterDescriptor_GpuCounterGroup_UNCLASSIFIED = 0,
11697   GpuCounterDescriptor_GpuCounterGroup_SYSTEM = 1,
11698   GpuCounterDescriptor_GpuCounterGroup_VERTICES = 2,
11699   GpuCounterDescriptor_GpuCounterGroup_FRAGMENTS = 3,
11700   GpuCounterDescriptor_GpuCounterGroup_PRIMITIVES = 4,
11701   GpuCounterDescriptor_GpuCounterGroup_MEMORY = 5,
11702   GpuCounterDescriptor_GpuCounterGroup_COMPUTE = 6,
11703 };
11704 enum GpuCounterDescriptor_MeasureUnit : int {
11705   GpuCounterDescriptor_MeasureUnit_NONE = 0,
11706   GpuCounterDescriptor_MeasureUnit_BIT = 1,
11707   GpuCounterDescriptor_MeasureUnit_KILOBIT = 2,
11708   GpuCounterDescriptor_MeasureUnit_MEGABIT = 3,
11709   GpuCounterDescriptor_MeasureUnit_GIGABIT = 4,
11710   GpuCounterDescriptor_MeasureUnit_TERABIT = 5,
11711   GpuCounterDescriptor_MeasureUnit_PETABIT = 6,
11712   GpuCounterDescriptor_MeasureUnit_BYTE = 7,
11713   GpuCounterDescriptor_MeasureUnit_KILOBYTE = 8,
11714   GpuCounterDescriptor_MeasureUnit_MEGABYTE = 9,
11715   GpuCounterDescriptor_MeasureUnit_GIGABYTE = 10,
11716   GpuCounterDescriptor_MeasureUnit_TERABYTE = 11,
11717   GpuCounterDescriptor_MeasureUnit_PETABYTE = 12,
11718   GpuCounterDescriptor_MeasureUnit_HERTZ = 13,
11719   GpuCounterDescriptor_MeasureUnit_KILOHERTZ = 14,
11720   GpuCounterDescriptor_MeasureUnit_MEGAHERTZ = 15,
11721   GpuCounterDescriptor_MeasureUnit_GIGAHERTZ = 16,
11722   GpuCounterDescriptor_MeasureUnit_TERAHERTZ = 17,
11723   GpuCounterDescriptor_MeasureUnit_PETAHERTZ = 18,
11724   GpuCounterDescriptor_MeasureUnit_NANOSECOND = 19,
11725   GpuCounterDescriptor_MeasureUnit_MICROSECOND = 20,
11726   GpuCounterDescriptor_MeasureUnit_MILLISECOND = 21,
11727   GpuCounterDescriptor_MeasureUnit_SECOND = 22,
11728   GpuCounterDescriptor_MeasureUnit_MINUTE = 23,
11729   GpuCounterDescriptor_MeasureUnit_HOUR = 24,
11730   GpuCounterDescriptor_MeasureUnit_VERTEX = 25,
11731   GpuCounterDescriptor_MeasureUnit_PIXEL = 26,
11732   GpuCounterDescriptor_MeasureUnit_TRIANGLE = 27,
11733   GpuCounterDescriptor_MeasureUnit_PRIMITIVE = 38,
11734   GpuCounterDescriptor_MeasureUnit_FRAGMENT = 39,
11735   GpuCounterDescriptor_MeasureUnit_MILLIWATT = 28,
11736   GpuCounterDescriptor_MeasureUnit_WATT = 29,
11737   GpuCounterDescriptor_MeasureUnit_KILOWATT = 30,
11738   GpuCounterDescriptor_MeasureUnit_JOULE = 31,
11739   GpuCounterDescriptor_MeasureUnit_VOLT = 32,
11740   GpuCounterDescriptor_MeasureUnit_AMPERE = 33,
11741   GpuCounterDescriptor_MeasureUnit_CELSIUS = 34,
11742   GpuCounterDescriptor_MeasureUnit_FAHRENHEIT = 35,
11743   GpuCounterDescriptor_MeasureUnit_KELVIN = 36,
11744   GpuCounterDescriptor_MeasureUnit_PERCENT = 37,
11745   GpuCounterDescriptor_MeasureUnit_INSTRUCTION = 40,
11746 };
11747 
11748 class PERFETTO_EXPORT GpuCounterDescriptor : public ::protozero::CppMessageObj {
11749  public:
11750   using GpuCounterSpec = GpuCounterDescriptor_GpuCounterSpec;
11751   using GpuCounterBlock = GpuCounterDescriptor_GpuCounterBlock;
11752   using GpuCounterGroup = GpuCounterDescriptor_GpuCounterGroup;
11753   static constexpr auto UNCLASSIFIED = GpuCounterDescriptor_GpuCounterGroup_UNCLASSIFIED;
11754   static constexpr auto SYSTEM = GpuCounterDescriptor_GpuCounterGroup_SYSTEM;
11755   static constexpr auto VERTICES = GpuCounterDescriptor_GpuCounterGroup_VERTICES;
11756   static constexpr auto FRAGMENTS = GpuCounterDescriptor_GpuCounterGroup_FRAGMENTS;
11757   static constexpr auto PRIMITIVES = GpuCounterDescriptor_GpuCounterGroup_PRIMITIVES;
11758   static constexpr auto MEMORY = GpuCounterDescriptor_GpuCounterGroup_MEMORY;
11759   static constexpr auto COMPUTE = GpuCounterDescriptor_GpuCounterGroup_COMPUTE;
11760   static constexpr auto GpuCounterGroup_MIN = GpuCounterDescriptor_GpuCounterGroup_UNCLASSIFIED;
11761   static constexpr auto GpuCounterGroup_MAX = GpuCounterDescriptor_GpuCounterGroup_COMPUTE;
11762   using MeasureUnit = GpuCounterDescriptor_MeasureUnit;
11763   static constexpr auto NONE = GpuCounterDescriptor_MeasureUnit_NONE;
11764   static constexpr auto BIT = GpuCounterDescriptor_MeasureUnit_BIT;
11765   static constexpr auto KILOBIT = GpuCounterDescriptor_MeasureUnit_KILOBIT;
11766   static constexpr auto MEGABIT = GpuCounterDescriptor_MeasureUnit_MEGABIT;
11767   static constexpr auto GIGABIT = GpuCounterDescriptor_MeasureUnit_GIGABIT;
11768   static constexpr auto TERABIT = GpuCounterDescriptor_MeasureUnit_TERABIT;
11769   static constexpr auto PETABIT = GpuCounterDescriptor_MeasureUnit_PETABIT;
11770   static constexpr auto BYTE = GpuCounterDescriptor_MeasureUnit_BYTE;
11771   static constexpr auto KILOBYTE = GpuCounterDescriptor_MeasureUnit_KILOBYTE;
11772   static constexpr auto MEGABYTE = GpuCounterDescriptor_MeasureUnit_MEGABYTE;
11773   static constexpr auto GIGABYTE = GpuCounterDescriptor_MeasureUnit_GIGABYTE;
11774   static constexpr auto TERABYTE = GpuCounterDescriptor_MeasureUnit_TERABYTE;
11775   static constexpr auto PETABYTE = GpuCounterDescriptor_MeasureUnit_PETABYTE;
11776   static constexpr auto HERTZ = GpuCounterDescriptor_MeasureUnit_HERTZ;
11777   static constexpr auto KILOHERTZ = GpuCounterDescriptor_MeasureUnit_KILOHERTZ;
11778   static constexpr auto MEGAHERTZ = GpuCounterDescriptor_MeasureUnit_MEGAHERTZ;
11779   static constexpr auto GIGAHERTZ = GpuCounterDescriptor_MeasureUnit_GIGAHERTZ;
11780   static constexpr auto TERAHERTZ = GpuCounterDescriptor_MeasureUnit_TERAHERTZ;
11781   static constexpr auto PETAHERTZ = GpuCounterDescriptor_MeasureUnit_PETAHERTZ;
11782   static constexpr auto NANOSECOND = GpuCounterDescriptor_MeasureUnit_NANOSECOND;
11783   static constexpr auto MICROSECOND = GpuCounterDescriptor_MeasureUnit_MICROSECOND;
11784   static constexpr auto MILLISECOND = GpuCounterDescriptor_MeasureUnit_MILLISECOND;
11785   static constexpr auto SECOND = GpuCounterDescriptor_MeasureUnit_SECOND;
11786   static constexpr auto MINUTE = GpuCounterDescriptor_MeasureUnit_MINUTE;
11787   static constexpr auto HOUR = GpuCounterDescriptor_MeasureUnit_HOUR;
11788   static constexpr auto VERTEX = GpuCounterDescriptor_MeasureUnit_VERTEX;
11789   static constexpr auto PIXEL = GpuCounterDescriptor_MeasureUnit_PIXEL;
11790   static constexpr auto TRIANGLE = GpuCounterDescriptor_MeasureUnit_TRIANGLE;
11791   static constexpr auto PRIMITIVE = GpuCounterDescriptor_MeasureUnit_PRIMITIVE;
11792   static constexpr auto FRAGMENT = GpuCounterDescriptor_MeasureUnit_FRAGMENT;
11793   static constexpr auto MILLIWATT = GpuCounterDescriptor_MeasureUnit_MILLIWATT;
11794   static constexpr auto WATT = GpuCounterDescriptor_MeasureUnit_WATT;
11795   static constexpr auto KILOWATT = GpuCounterDescriptor_MeasureUnit_KILOWATT;
11796   static constexpr auto JOULE = GpuCounterDescriptor_MeasureUnit_JOULE;
11797   static constexpr auto VOLT = GpuCounterDescriptor_MeasureUnit_VOLT;
11798   static constexpr auto AMPERE = GpuCounterDescriptor_MeasureUnit_AMPERE;
11799   static constexpr auto CELSIUS = GpuCounterDescriptor_MeasureUnit_CELSIUS;
11800   static constexpr auto FAHRENHEIT = GpuCounterDescriptor_MeasureUnit_FAHRENHEIT;
11801   static constexpr auto KELVIN = GpuCounterDescriptor_MeasureUnit_KELVIN;
11802   static constexpr auto PERCENT = GpuCounterDescriptor_MeasureUnit_PERCENT;
11803   static constexpr auto INSTRUCTION = GpuCounterDescriptor_MeasureUnit_INSTRUCTION;
11804   static constexpr auto MeasureUnit_MIN = GpuCounterDescriptor_MeasureUnit_NONE;
11805   static constexpr auto MeasureUnit_MAX = GpuCounterDescriptor_MeasureUnit_INSTRUCTION;
11806   enum FieldNumbers {
11807     kSpecsFieldNumber = 1,
11808     kBlocksFieldNumber = 2,
11809     kMinSamplingPeriodNsFieldNumber = 3,
11810     kMaxSamplingPeriodNsFieldNumber = 4,
11811     kSupportsInstrumentedSamplingFieldNumber = 5,
11812   };
11813 
11814   GpuCounterDescriptor();
11815   ~GpuCounterDescriptor() override;
11816   GpuCounterDescriptor(GpuCounterDescriptor&&) noexcept;
11817   GpuCounterDescriptor& operator=(GpuCounterDescriptor&&);
11818   GpuCounterDescriptor(const GpuCounterDescriptor&);
11819   GpuCounterDescriptor& operator=(const GpuCounterDescriptor&);
11820   bool operator==(const GpuCounterDescriptor&) const;
operator !=(const GpuCounterDescriptor & other) const11821   bool operator!=(const GpuCounterDescriptor& other) const { return !(*this == other); }
11822 
11823   bool ParseFromArray(const void*, size_t) override;
11824   std::string SerializeAsString() const override;
11825   std::vector<uint8_t> SerializeAsArray() const override;
11826   void Serialize(::protozero::Message*) const;
11827 
specs() const11828   const std::vector<GpuCounterDescriptor_GpuCounterSpec>& specs() const { return specs_; }
mutable_specs()11829   std::vector<GpuCounterDescriptor_GpuCounterSpec>* mutable_specs() { return &specs_; }
11830   int specs_size() const;
11831   void clear_specs();
11832   GpuCounterDescriptor_GpuCounterSpec* add_specs();
11833 
blocks() const11834   const std::vector<GpuCounterDescriptor_GpuCounterBlock>& blocks() const { return blocks_; }
mutable_blocks()11835   std::vector<GpuCounterDescriptor_GpuCounterBlock>* mutable_blocks() { return &blocks_; }
11836   int blocks_size() const;
11837   void clear_blocks();
11838   GpuCounterDescriptor_GpuCounterBlock* add_blocks();
11839 
has_min_sampling_period_ns() const11840   bool has_min_sampling_period_ns() const { return _has_field_[3]; }
min_sampling_period_ns() const11841   uint64_t min_sampling_period_ns() const { return min_sampling_period_ns_; }
set_min_sampling_period_ns(uint64_t value)11842   void set_min_sampling_period_ns(uint64_t value) { min_sampling_period_ns_ = value; _has_field_.set(3); }
11843 
has_max_sampling_period_ns() const11844   bool has_max_sampling_period_ns() const { return _has_field_[4]; }
max_sampling_period_ns() const11845   uint64_t max_sampling_period_ns() const { return max_sampling_period_ns_; }
set_max_sampling_period_ns(uint64_t value)11846   void set_max_sampling_period_ns(uint64_t value) { max_sampling_period_ns_ = value; _has_field_.set(4); }
11847 
has_supports_instrumented_sampling() const11848   bool has_supports_instrumented_sampling() const { return _has_field_[5]; }
supports_instrumented_sampling() const11849   bool supports_instrumented_sampling() const { return supports_instrumented_sampling_; }
set_supports_instrumented_sampling(bool value)11850   void set_supports_instrumented_sampling(bool value) { supports_instrumented_sampling_ = value; _has_field_.set(5); }
11851 
11852  private:
11853   std::vector<GpuCounterDescriptor_GpuCounterSpec> specs_;
11854   std::vector<GpuCounterDescriptor_GpuCounterBlock> blocks_;
11855   uint64_t min_sampling_period_ns_{};
11856   uint64_t max_sampling_period_ns_{};
11857   bool supports_instrumented_sampling_{};
11858 
11859   // Allows to preserve unknown protobuf fields for compatibility
11860   // with future versions of .proto files.
11861   std::string unknown_fields_;
11862 
11863   std::bitset<6> _has_field_{};
11864 };
11865 
11866 
11867 class PERFETTO_EXPORT GpuCounterDescriptor_GpuCounterBlock : public ::protozero::CppMessageObj {
11868  public:
11869   enum FieldNumbers {
11870     kBlockIdFieldNumber = 1,
11871     kBlockCapacityFieldNumber = 2,
11872     kNameFieldNumber = 3,
11873     kDescriptionFieldNumber = 4,
11874     kCounterIdsFieldNumber = 5,
11875   };
11876 
11877   GpuCounterDescriptor_GpuCounterBlock();
11878   ~GpuCounterDescriptor_GpuCounterBlock() override;
11879   GpuCounterDescriptor_GpuCounterBlock(GpuCounterDescriptor_GpuCounterBlock&&) noexcept;
11880   GpuCounterDescriptor_GpuCounterBlock& operator=(GpuCounterDescriptor_GpuCounterBlock&&);
11881   GpuCounterDescriptor_GpuCounterBlock(const GpuCounterDescriptor_GpuCounterBlock&);
11882   GpuCounterDescriptor_GpuCounterBlock& operator=(const GpuCounterDescriptor_GpuCounterBlock&);
11883   bool operator==(const GpuCounterDescriptor_GpuCounterBlock&) const;
operator !=(const GpuCounterDescriptor_GpuCounterBlock & other) const11884   bool operator!=(const GpuCounterDescriptor_GpuCounterBlock& other) const { return !(*this == other); }
11885 
11886   bool ParseFromArray(const void*, size_t) override;
11887   std::string SerializeAsString() const override;
11888   std::vector<uint8_t> SerializeAsArray() const override;
11889   void Serialize(::protozero::Message*) const;
11890 
has_block_id() const11891   bool has_block_id() const { return _has_field_[1]; }
block_id() const11892   uint32_t block_id() const { return block_id_; }
set_block_id(uint32_t value)11893   void set_block_id(uint32_t value) { block_id_ = value; _has_field_.set(1); }
11894 
has_block_capacity() const11895   bool has_block_capacity() const { return _has_field_[2]; }
block_capacity() const11896   uint32_t block_capacity() const { return block_capacity_; }
set_block_capacity(uint32_t value)11897   void set_block_capacity(uint32_t value) { block_capacity_ = value; _has_field_.set(2); }
11898 
has_name() const11899   bool has_name() const { return _has_field_[3]; }
name() const11900   const std::string& name() const { return name_; }
set_name(const std::string & value)11901   void set_name(const std::string& value) { name_ = value; _has_field_.set(3); }
11902 
has_description() const11903   bool has_description() const { return _has_field_[4]; }
description() const11904   const std::string& description() const { return description_; }
set_description(const std::string & value)11905   void set_description(const std::string& value) { description_ = value; _has_field_.set(4); }
11906 
counter_ids() const11907   const std::vector<uint32_t>& counter_ids() const { return counter_ids_; }
mutable_counter_ids()11908   std::vector<uint32_t>* mutable_counter_ids() { return &counter_ids_; }
counter_ids_size() const11909   int counter_ids_size() const { return static_cast<int>(counter_ids_.size()); }
clear_counter_ids()11910   void clear_counter_ids() { counter_ids_.clear(); }
add_counter_ids(uint32_t value)11911   void add_counter_ids(uint32_t value) { counter_ids_.emplace_back(value); }
add_counter_ids()11912   uint32_t* add_counter_ids() { counter_ids_.emplace_back(); return &counter_ids_.back(); }
11913 
11914  private:
11915   uint32_t block_id_{};
11916   uint32_t block_capacity_{};
11917   std::string name_{};
11918   std::string description_{};
11919   std::vector<uint32_t> counter_ids_;
11920 
11921   // Allows to preserve unknown protobuf fields for compatibility
11922   // with future versions of .proto files.
11923   std::string unknown_fields_;
11924 
11925   std::bitset<6> _has_field_{};
11926 };
11927 
11928 
11929 class PERFETTO_EXPORT GpuCounterDescriptor_GpuCounterSpec : public ::protozero::CppMessageObj {
11930  public:
11931   enum FieldNumbers {
11932     kCounterIdFieldNumber = 1,
11933     kNameFieldNumber = 2,
11934     kDescriptionFieldNumber = 3,
11935     kIntPeakValueFieldNumber = 5,
11936     kDoublePeakValueFieldNumber = 6,
11937     kNumeratorUnitsFieldNumber = 7,
11938     kDenominatorUnitsFieldNumber = 8,
11939     kSelectByDefaultFieldNumber = 9,
11940     kGroupsFieldNumber = 10,
11941   };
11942 
11943   GpuCounterDescriptor_GpuCounterSpec();
11944   ~GpuCounterDescriptor_GpuCounterSpec() override;
11945   GpuCounterDescriptor_GpuCounterSpec(GpuCounterDescriptor_GpuCounterSpec&&) noexcept;
11946   GpuCounterDescriptor_GpuCounterSpec& operator=(GpuCounterDescriptor_GpuCounterSpec&&);
11947   GpuCounterDescriptor_GpuCounterSpec(const GpuCounterDescriptor_GpuCounterSpec&);
11948   GpuCounterDescriptor_GpuCounterSpec& operator=(const GpuCounterDescriptor_GpuCounterSpec&);
11949   bool operator==(const GpuCounterDescriptor_GpuCounterSpec&) const;
operator !=(const GpuCounterDescriptor_GpuCounterSpec & other) const11950   bool operator!=(const GpuCounterDescriptor_GpuCounterSpec& other) const { return !(*this == other); }
11951 
11952   bool ParseFromArray(const void*, size_t) override;
11953   std::string SerializeAsString() const override;
11954   std::vector<uint8_t> SerializeAsArray() const override;
11955   void Serialize(::protozero::Message*) const;
11956 
has_counter_id() const11957   bool has_counter_id() const { return _has_field_[1]; }
counter_id() const11958   uint32_t counter_id() const { return counter_id_; }
set_counter_id(uint32_t value)11959   void set_counter_id(uint32_t value) { counter_id_ = value; _has_field_.set(1); }
11960 
has_name() const11961   bool has_name() const { return _has_field_[2]; }
name() const11962   const std::string& name() const { return name_; }
set_name(const std::string & value)11963   void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
11964 
has_description() const11965   bool has_description() const { return _has_field_[3]; }
description() const11966   const std::string& description() const { return description_; }
set_description(const std::string & value)11967   void set_description(const std::string& value) { description_ = value; _has_field_.set(3); }
11968 
has_int_peak_value() const11969   bool has_int_peak_value() const { return _has_field_[5]; }
int_peak_value() const11970   int64_t int_peak_value() const { return int_peak_value_; }
set_int_peak_value(int64_t value)11971   void set_int_peak_value(int64_t value) { int_peak_value_ = value; _has_field_.set(5); }
11972 
has_double_peak_value() const11973   bool has_double_peak_value() const { return _has_field_[6]; }
double_peak_value() const11974   double double_peak_value() const { return double_peak_value_; }
set_double_peak_value(double value)11975   void set_double_peak_value(double value) { double_peak_value_ = value; _has_field_.set(6); }
11976 
numerator_units() const11977   const std::vector<GpuCounterDescriptor_MeasureUnit>& numerator_units() const { return numerator_units_; }
mutable_numerator_units()11978   std::vector<GpuCounterDescriptor_MeasureUnit>* mutable_numerator_units() { return &numerator_units_; }
numerator_units_size() const11979   int numerator_units_size() const { return static_cast<int>(numerator_units_.size()); }
clear_numerator_units()11980   void clear_numerator_units() { numerator_units_.clear(); }
add_numerator_units(GpuCounterDescriptor_MeasureUnit value)11981   void add_numerator_units(GpuCounterDescriptor_MeasureUnit value) { numerator_units_.emplace_back(value); }
add_numerator_units()11982   GpuCounterDescriptor_MeasureUnit* add_numerator_units() { numerator_units_.emplace_back(); return &numerator_units_.back(); }
11983 
denominator_units() const11984   const std::vector<GpuCounterDescriptor_MeasureUnit>& denominator_units() const { return denominator_units_; }
mutable_denominator_units()11985   std::vector<GpuCounterDescriptor_MeasureUnit>* mutable_denominator_units() { return &denominator_units_; }
denominator_units_size() const11986   int denominator_units_size() const { return static_cast<int>(denominator_units_.size()); }
clear_denominator_units()11987   void clear_denominator_units() { denominator_units_.clear(); }
add_denominator_units(GpuCounterDescriptor_MeasureUnit value)11988   void add_denominator_units(GpuCounterDescriptor_MeasureUnit value) { denominator_units_.emplace_back(value); }
add_denominator_units()11989   GpuCounterDescriptor_MeasureUnit* add_denominator_units() { denominator_units_.emplace_back(); return &denominator_units_.back(); }
11990 
has_select_by_default() const11991   bool has_select_by_default() const { return _has_field_[9]; }
select_by_default() const11992   bool select_by_default() const { return select_by_default_; }
set_select_by_default(bool value)11993   void set_select_by_default(bool value) { select_by_default_ = value; _has_field_.set(9); }
11994 
groups() const11995   const std::vector<GpuCounterDescriptor_GpuCounterGroup>& groups() const { return groups_; }
mutable_groups()11996   std::vector<GpuCounterDescriptor_GpuCounterGroup>* mutable_groups() { return &groups_; }
groups_size() const11997   int groups_size() const { return static_cast<int>(groups_.size()); }
clear_groups()11998   void clear_groups() { groups_.clear(); }
add_groups(GpuCounterDescriptor_GpuCounterGroup value)11999   void add_groups(GpuCounterDescriptor_GpuCounterGroup value) { groups_.emplace_back(value); }
add_groups()12000   GpuCounterDescriptor_GpuCounterGroup* add_groups() { groups_.emplace_back(); return &groups_.back(); }
12001 
12002  private:
12003   uint32_t counter_id_{};
12004   std::string name_{};
12005   std::string description_{};
12006   int64_t int_peak_value_{};
12007   double double_peak_value_{};
12008   std::vector<GpuCounterDescriptor_MeasureUnit> numerator_units_;
12009   std::vector<GpuCounterDescriptor_MeasureUnit> denominator_units_;
12010   bool select_by_default_{};
12011   std::vector<GpuCounterDescriptor_GpuCounterGroup> groups_;
12012 
12013   // Allows to preserve unknown protobuf fields for compatibility
12014   // with future versions of .proto files.
12015   std::string unknown_fields_;
12016 
12017   std::bitset<11> _has_field_{};
12018 };
12019 
12020 }  // namespace perfetto
12021 }  // namespace protos
12022 }  // namespace gen
12023 
12024 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_GPU_COUNTER_DESCRIPTOR_PROTO_CPP_H_
12025 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
12026 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
12027 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
12028 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
12029 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
12030 #if defined(__GNUC__) || defined(__clang__)
12031 #pragma GCC diagnostic push
12032 #pragma GCC diagnostic ignored "-Wfloat-equal"
12033 #endif
12034 // gen_amalgamated expanded: #include "protos/perfetto/common/gpu_counter_descriptor.gen.h"
12035 
12036 namespace perfetto {
12037 namespace protos {
12038 namespace gen {
12039 
12040 GpuCounterDescriptor::GpuCounterDescriptor() = default;
12041 GpuCounterDescriptor::~GpuCounterDescriptor() = default;
12042 GpuCounterDescriptor::GpuCounterDescriptor(const GpuCounterDescriptor&) = default;
12043 GpuCounterDescriptor& GpuCounterDescriptor::operator=(const GpuCounterDescriptor&) = default;
12044 GpuCounterDescriptor::GpuCounterDescriptor(GpuCounterDescriptor&&) noexcept = default;
12045 GpuCounterDescriptor& GpuCounterDescriptor::operator=(GpuCounterDescriptor&&) = default;
12046 
operator ==(const GpuCounterDescriptor & other) const12047 bool GpuCounterDescriptor::operator==(const GpuCounterDescriptor& other) const {
12048   return unknown_fields_ == other.unknown_fields_
12049    && specs_ == other.specs_
12050    && blocks_ == other.blocks_
12051    && min_sampling_period_ns_ == other.min_sampling_period_ns_
12052    && max_sampling_period_ns_ == other.max_sampling_period_ns_
12053    && supports_instrumented_sampling_ == other.supports_instrumented_sampling_;
12054 }
12055 
specs_size() const12056 int GpuCounterDescriptor::specs_size() const { return static_cast<int>(specs_.size()); }
clear_specs()12057 void GpuCounterDescriptor::clear_specs() { specs_.clear(); }
add_specs()12058 GpuCounterDescriptor_GpuCounterSpec* GpuCounterDescriptor::add_specs() { specs_.emplace_back(); return &specs_.back(); }
blocks_size() const12059 int GpuCounterDescriptor::blocks_size() const { return static_cast<int>(blocks_.size()); }
clear_blocks()12060 void GpuCounterDescriptor::clear_blocks() { blocks_.clear(); }
add_blocks()12061 GpuCounterDescriptor_GpuCounterBlock* GpuCounterDescriptor::add_blocks() { blocks_.emplace_back(); return &blocks_.back(); }
ParseFromArray(const void * raw,size_t size)12062 bool GpuCounterDescriptor::ParseFromArray(const void* raw, size_t size) {
12063   specs_.clear();
12064   blocks_.clear();
12065   unknown_fields_.clear();
12066   bool packed_error = false;
12067 
12068   ::protozero::ProtoDecoder dec(raw, size);
12069   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
12070     if (field.id() < _has_field_.size()) {
12071       _has_field_.set(field.id());
12072     }
12073     switch (field.id()) {
12074       case 1 /* specs */:
12075         specs_.emplace_back();
12076         specs_.back().ParseFromArray(field.data(), field.size());
12077         break;
12078       case 2 /* blocks */:
12079         blocks_.emplace_back();
12080         blocks_.back().ParseFromArray(field.data(), field.size());
12081         break;
12082       case 3 /* min_sampling_period_ns */:
12083         field.get(&min_sampling_period_ns_);
12084         break;
12085       case 4 /* max_sampling_period_ns */:
12086         field.get(&max_sampling_period_ns_);
12087         break;
12088       case 5 /* supports_instrumented_sampling */:
12089         field.get(&supports_instrumented_sampling_);
12090         break;
12091       default:
12092         field.SerializeAndAppendTo(&unknown_fields_);
12093         break;
12094     }
12095   }
12096   return !packed_error && !dec.bytes_left();
12097 }
12098 
SerializeAsString() const12099 std::string GpuCounterDescriptor::SerializeAsString() const {
12100   ::protozero::HeapBuffered<::protozero::Message> msg;
12101   Serialize(msg.get());
12102   return msg.SerializeAsString();
12103 }
12104 
SerializeAsArray() const12105 std::vector<uint8_t> GpuCounterDescriptor::SerializeAsArray() const {
12106   ::protozero::HeapBuffered<::protozero::Message> msg;
12107   Serialize(msg.get());
12108   return msg.SerializeAsArray();
12109 }
12110 
Serialize(::protozero::Message * msg) const12111 void GpuCounterDescriptor::Serialize(::protozero::Message* msg) const {
12112   // Field 1: specs
12113   for (auto& it : specs_) {
12114     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
12115   }
12116 
12117   // Field 2: blocks
12118   for (auto& it : blocks_) {
12119     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
12120   }
12121 
12122   // Field 3: min_sampling_period_ns
12123   if (_has_field_[3]) {
12124     msg->AppendVarInt(3, min_sampling_period_ns_);
12125   }
12126 
12127   // Field 4: max_sampling_period_ns
12128   if (_has_field_[4]) {
12129     msg->AppendVarInt(4, max_sampling_period_ns_);
12130   }
12131 
12132   // Field 5: supports_instrumented_sampling
12133   if (_has_field_[5]) {
12134     msg->AppendTinyVarInt(5, supports_instrumented_sampling_);
12135   }
12136 
12137   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
12138 }
12139 
12140 
12141 GpuCounterDescriptor_GpuCounterBlock::GpuCounterDescriptor_GpuCounterBlock() = default;
12142 GpuCounterDescriptor_GpuCounterBlock::~GpuCounterDescriptor_GpuCounterBlock() = default;
12143 GpuCounterDescriptor_GpuCounterBlock::GpuCounterDescriptor_GpuCounterBlock(const GpuCounterDescriptor_GpuCounterBlock&) = default;
12144 GpuCounterDescriptor_GpuCounterBlock& GpuCounterDescriptor_GpuCounterBlock::operator=(const GpuCounterDescriptor_GpuCounterBlock&) = default;
12145 GpuCounterDescriptor_GpuCounterBlock::GpuCounterDescriptor_GpuCounterBlock(GpuCounterDescriptor_GpuCounterBlock&&) noexcept = default;
12146 GpuCounterDescriptor_GpuCounterBlock& GpuCounterDescriptor_GpuCounterBlock::operator=(GpuCounterDescriptor_GpuCounterBlock&&) = default;
12147 
operator ==(const GpuCounterDescriptor_GpuCounterBlock & other) const12148 bool GpuCounterDescriptor_GpuCounterBlock::operator==(const GpuCounterDescriptor_GpuCounterBlock& other) const {
12149   return unknown_fields_ == other.unknown_fields_
12150    && block_id_ == other.block_id_
12151    && block_capacity_ == other.block_capacity_
12152    && name_ == other.name_
12153    && description_ == other.description_
12154    && counter_ids_ == other.counter_ids_;
12155 }
12156 
ParseFromArray(const void * raw,size_t size)12157 bool GpuCounterDescriptor_GpuCounterBlock::ParseFromArray(const void* raw, size_t size) {
12158   counter_ids_.clear();
12159   unknown_fields_.clear();
12160   bool packed_error = false;
12161 
12162   ::protozero::ProtoDecoder dec(raw, size);
12163   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
12164     if (field.id() < _has_field_.size()) {
12165       _has_field_.set(field.id());
12166     }
12167     switch (field.id()) {
12168       case 1 /* block_id */:
12169         field.get(&block_id_);
12170         break;
12171       case 2 /* block_capacity */:
12172         field.get(&block_capacity_);
12173         break;
12174       case 3 /* name */:
12175         field.get(&name_);
12176         break;
12177       case 4 /* description */:
12178         field.get(&description_);
12179         break;
12180       case 5 /* counter_ids */:
12181         counter_ids_.emplace_back();
12182         field.get(&counter_ids_.back());
12183         break;
12184       default:
12185         field.SerializeAndAppendTo(&unknown_fields_);
12186         break;
12187     }
12188   }
12189   return !packed_error && !dec.bytes_left();
12190 }
12191 
SerializeAsString() const12192 std::string GpuCounterDescriptor_GpuCounterBlock::SerializeAsString() const {
12193   ::protozero::HeapBuffered<::protozero::Message> msg;
12194   Serialize(msg.get());
12195   return msg.SerializeAsString();
12196 }
12197 
SerializeAsArray() const12198 std::vector<uint8_t> GpuCounterDescriptor_GpuCounterBlock::SerializeAsArray() const {
12199   ::protozero::HeapBuffered<::protozero::Message> msg;
12200   Serialize(msg.get());
12201   return msg.SerializeAsArray();
12202 }
12203 
Serialize(::protozero::Message * msg) const12204 void GpuCounterDescriptor_GpuCounterBlock::Serialize(::protozero::Message* msg) const {
12205   // Field 1: block_id
12206   if (_has_field_[1]) {
12207     msg->AppendVarInt(1, block_id_);
12208   }
12209 
12210   // Field 2: block_capacity
12211   if (_has_field_[2]) {
12212     msg->AppendVarInt(2, block_capacity_);
12213   }
12214 
12215   // Field 3: name
12216   if (_has_field_[3]) {
12217     msg->AppendString(3, name_);
12218   }
12219 
12220   // Field 4: description
12221   if (_has_field_[4]) {
12222     msg->AppendString(4, description_);
12223   }
12224 
12225   // Field 5: counter_ids
12226   for (auto& it : counter_ids_) {
12227     msg->AppendVarInt(5, it);
12228   }
12229 
12230   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
12231 }
12232 
12233 
12234 GpuCounterDescriptor_GpuCounterSpec::GpuCounterDescriptor_GpuCounterSpec() = default;
12235 GpuCounterDescriptor_GpuCounterSpec::~GpuCounterDescriptor_GpuCounterSpec() = default;
12236 GpuCounterDescriptor_GpuCounterSpec::GpuCounterDescriptor_GpuCounterSpec(const GpuCounterDescriptor_GpuCounterSpec&) = default;
12237 GpuCounterDescriptor_GpuCounterSpec& GpuCounterDescriptor_GpuCounterSpec::operator=(const GpuCounterDescriptor_GpuCounterSpec&) = default;
12238 GpuCounterDescriptor_GpuCounterSpec::GpuCounterDescriptor_GpuCounterSpec(GpuCounterDescriptor_GpuCounterSpec&&) noexcept = default;
12239 GpuCounterDescriptor_GpuCounterSpec& GpuCounterDescriptor_GpuCounterSpec::operator=(GpuCounterDescriptor_GpuCounterSpec&&) = default;
12240 
operator ==(const GpuCounterDescriptor_GpuCounterSpec & other) const12241 bool GpuCounterDescriptor_GpuCounterSpec::operator==(const GpuCounterDescriptor_GpuCounterSpec& other) const {
12242   return unknown_fields_ == other.unknown_fields_
12243    && counter_id_ == other.counter_id_
12244    && name_ == other.name_
12245    && description_ == other.description_
12246    && int_peak_value_ == other.int_peak_value_
12247    && double_peak_value_ == other.double_peak_value_
12248    && numerator_units_ == other.numerator_units_
12249    && denominator_units_ == other.denominator_units_
12250    && select_by_default_ == other.select_by_default_
12251    && groups_ == other.groups_;
12252 }
12253 
ParseFromArray(const void * raw,size_t size)12254 bool GpuCounterDescriptor_GpuCounterSpec::ParseFromArray(const void* raw, size_t size) {
12255   numerator_units_.clear();
12256   denominator_units_.clear();
12257   groups_.clear();
12258   unknown_fields_.clear();
12259   bool packed_error = false;
12260 
12261   ::protozero::ProtoDecoder dec(raw, size);
12262   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
12263     if (field.id() < _has_field_.size()) {
12264       _has_field_.set(field.id());
12265     }
12266     switch (field.id()) {
12267       case 1 /* counter_id */:
12268         field.get(&counter_id_);
12269         break;
12270       case 2 /* name */:
12271         field.get(&name_);
12272         break;
12273       case 3 /* description */:
12274         field.get(&description_);
12275         break;
12276       case 5 /* int_peak_value */:
12277         field.get(&int_peak_value_);
12278         break;
12279       case 6 /* double_peak_value */:
12280         field.get(&double_peak_value_);
12281         break;
12282       case 7 /* numerator_units */:
12283         numerator_units_.emplace_back();
12284         field.get(&numerator_units_.back());
12285         break;
12286       case 8 /* denominator_units */:
12287         denominator_units_.emplace_back();
12288         field.get(&denominator_units_.back());
12289         break;
12290       case 9 /* select_by_default */:
12291         field.get(&select_by_default_);
12292         break;
12293       case 10 /* groups */:
12294         groups_.emplace_back();
12295         field.get(&groups_.back());
12296         break;
12297       default:
12298         field.SerializeAndAppendTo(&unknown_fields_);
12299         break;
12300     }
12301   }
12302   return !packed_error && !dec.bytes_left();
12303 }
12304 
SerializeAsString() const12305 std::string GpuCounterDescriptor_GpuCounterSpec::SerializeAsString() const {
12306   ::protozero::HeapBuffered<::protozero::Message> msg;
12307   Serialize(msg.get());
12308   return msg.SerializeAsString();
12309 }
12310 
SerializeAsArray() const12311 std::vector<uint8_t> GpuCounterDescriptor_GpuCounterSpec::SerializeAsArray() const {
12312   ::protozero::HeapBuffered<::protozero::Message> msg;
12313   Serialize(msg.get());
12314   return msg.SerializeAsArray();
12315 }
12316 
Serialize(::protozero::Message * msg) const12317 void GpuCounterDescriptor_GpuCounterSpec::Serialize(::protozero::Message* msg) const {
12318   // Field 1: counter_id
12319   if (_has_field_[1]) {
12320     msg->AppendVarInt(1, counter_id_);
12321   }
12322 
12323   // Field 2: name
12324   if (_has_field_[2]) {
12325     msg->AppendString(2, name_);
12326   }
12327 
12328   // Field 3: description
12329   if (_has_field_[3]) {
12330     msg->AppendString(3, description_);
12331   }
12332 
12333   // Field 5: int_peak_value
12334   if (_has_field_[5]) {
12335     msg->AppendVarInt(5, int_peak_value_);
12336   }
12337 
12338   // Field 6: double_peak_value
12339   if (_has_field_[6]) {
12340     msg->AppendFixed(6, double_peak_value_);
12341   }
12342 
12343   // Field 7: numerator_units
12344   for (auto& it : numerator_units_) {
12345     msg->AppendVarInt(7, it);
12346   }
12347 
12348   // Field 8: denominator_units
12349   for (auto& it : denominator_units_) {
12350     msg->AppendVarInt(8, it);
12351   }
12352 
12353   // Field 9: select_by_default
12354   if (_has_field_[9]) {
12355     msg->AppendTinyVarInt(9, select_by_default_);
12356   }
12357 
12358   // Field 10: groups
12359   for (auto& it : groups_) {
12360     msg->AppendVarInt(10, it);
12361   }
12362 
12363   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
12364 }
12365 
12366 }  // namespace perfetto
12367 }  // namespace protos
12368 }  // namespace gen
12369 #if defined(__GNUC__) || defined(__clang__)
12370 #pragma GCC diagnostic pop
12371 #endif
12372 // gen_amalgamated begin source: gen/protos/perfetto/common/interceptor_descriptor.gen.cc
12373 // gen_amalgamated begin header: gen/protos/perfetto/common/interceptor_descriptor.gen.h
12374 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
12375 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_INTERCEPTOR_DESCRIPTOR_PROTO_CPP_H_
12376 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_INTERCEPTOR_DESCRIPTOR_PROTO_CPP_H_
12377 
12378 #include <stdint.h>
12379 #include <bitset>
12380 #include <vector>
12381 #include <string>
12382 #include <type_traits>
12383 
12384 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
12385 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
12386 // gen_amalgamated expanded: #include "perfetto/base/export.h"
12387 
12388 namespace perfetto {
12389 namespace protos {
12390 namespace gen {
12391 class InterceptorDescriptor;
12392 }  // namespace perfetto
12393 }  // namespace protos
12394 }  // namespace gen
12395 
12396 namespace protozero {
12397 class Message;
12398 }  // namespace protozero
12399 
12400 namespace perfetto {
12401 namespace protos {
12402 namespace gen {
12403 
12404 class PERFETTO_EXPORT InterceptorDescriptor : public ::protozero::CppMessageObj {
12405  public:
12406   enum FieldNumbers {
12407     kNameFieldNumber = 1,
12408   };
12409 
12410   InterceptorDescriptor();
12411   ~InterceptorDescriptor() override;
12412   InterceptorDescriptor(InterceptorDescriptor&&) noexcept;
12413   InterceptorDescriptor& operator=(InterceptorDescriptor&&);
12414   InterceptorDescriptor(const InterceptorDescriptor&);
12415   InterceptorDescriptor& operator=(const InterceptorDescriptor&);
12416   bool operator==(const InterceptorDescriptor&) const;
operator !=(const InterceptorDescriptor & other) const12417   bool operator!=(const InterceptorDescriptor& other) const { return !(*this == other); }
12418 
12419   bool ParseFromArray(const void*, size_t) override;
12420   std::string SerializeAsString() const override;
12421   std::vector<uint8_t> SerializeAsArray() const override;
12422   void Serialize(::protozero::Message*) const;
12423 
has_name() const12424   bool has_name() const { return _has_field_[1]; }
name() const12425   const std::string& name() const { return name_; }
set_name(const std::string & value)12426   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
12427 
12428  private:
12429   std::string name_{};
12430 
12431   // Allows to preserve unknown protobuf fields for compatibility
12432   // with future versions of .proto files.
12433   std::string unknown_fields_;
12434 
12435   std::bitset<2> _has_field_{};
12436 };
12437 
12438 }  // namespace perfetto
12439 }  // namespace protos
12440 }  // namespace gen
12441 
12442 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_INTERCEPTOR_DESCRIPTOR_PROTO_CPP_H_
12443 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
12444 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
12445 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
12446 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
12447 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
12448 #if defined(__GNUC__) || defined(__clang__)
12449 #pragma GCC diagnostic push
12450 #pragma GCC diagnostic ignored "-Wfloat-equal"
12451 #endif
12452 // gen_amalgamated expanded: #include "protos/perfetto/common/interceptor_descriptor.gen.h"
12453 
12454 namespace perfetto {
12455 namespace protos {
12456 namespace gen {
12457 
12458 InterceptorDescriptor::InterceptorDescriptor() = default;
12459 InterceptorDescriptor::~InterceptorDescriptor() = default;
12460 InterceptorDescriptor::InterceptorDescriptor(const InterceptorDescriptor&) = default;
12461 InterceptorDescriptor& InterceptorDescriptor::operator=(const InterceptorDescriptor&) = default;
12462 InterceptorDescriptor::InterceptorDescriptor(InterceptorDescriptor&&) noexcept = default;
12463 InterceptorDescriptor& InterceptorDescriptor::operator=(InterceptorDescriptor&&) = default;
12464 
operator ==(const InterceptorDescriptor & other) const12465 bool InterceptorDescriptor::operator==(const InterceptorDescriptor& other) const {
12466   return unknown_fields_ == other.unknown_fields_
12467    && name_ == other.name_;
12468 }
12469 
ParseFromArray(const void * raw,size_t size)12470 bool InterceptorDescriptor::ParseFromArray(const void* raw, size_t size) {
12471   unknown_fields_.clear();
12472   bool packed_error = false;
12473 
12474   ::protozero::ProtoDecoder dec(raw, size);
12475   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
12476     if (field.id() < _has_field_.size()) {
12477       _has_field_.set(field.id());
12478     }
12479     switch (field.id()) {
12480       case 1 /* name */:
12481         field.get(&name_);
12482         break;
12483       default:
12484         field.SerializeAndAppendTo(&unknown_fields_);
12485         break;
12486     }
12487   }
12488   return !packed_error && !dec.bytes_left();
12489 }
12490 
SerializeAsString() const12491 std::string InterceptorDescriptor::SerializeAsString() const {
12492   ::protozero::HeapBuffered<::protozero::Message> msg;
12493   Serialize(msg.get());
12494   return msg.SerializeAsString();
12495 }
12496 
SerializeAsArray() const12497 std::vector<uint8_t> InterceptorDescriptor::SerializeAsArray() const {
12498   ::protozero::HeapBuffered<::protozero::Message> msg;
12499   Serialize(msg.get());
12500   return msg.SerializeAsArray();
12501 }
12502 
Serialize(::protozero::Message * msg) const12503 void InterceptorDescriptor::Serialize(::protozero::Message* msg) const {
12504   // Field 1: name
12505   if (_has_field_[1]) {
12506     msg->AppendString(1, name_);
12507   }
12508 
12509   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
12510 }
12511 
12512 }  // namespace perfetto
12513 }  // namespace protos
12514 }  // namespace gen
12515 #if defined(__GNUC__) || defined(__clang__)
12516 #pragma GCC diagnostic pop
12517 #endif
12518 // gen_amalgamated begin source: gen/protos/perfetto/common/observable_events.gen.cc
12519 // gen_amalgamated begin header: gen/protos/perfetto/common/observable_events.gen.h
12520 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
12521 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_OBSERVABLE_EVENTS_PROTO_CPP_H_
12522 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_OBSERVABLE_EVENTS_PROTO_CPP_H_
12523 
12524 #include <stdint.h>
12525 #include <bitset>
12526 #include <vector>
12527 #include <string>
12528 #include <type_traits>
12529 
12530 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
12531 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
12532 // gen_amalgamated expanded: #include "perfetto/base/export.h"
12533 
12534 namespace perfetto {
12535 namespace protos {
12536 namespace gen {
12537 class ObservableEvents;
12538 class ObservableEvents_DataSourceInstanceStateChange;
12539 enum ObservableEvents_Type : int;
12540 enum ObservableEvents_DataSourceInstanceState : int;
12541 }  // namespace perfetto
12542 }  // namespace protos
12543 }  // namespace gen
12544 
12545 namespace protozero {
12546 class Message;
12547 }  // namespace protozero
12548 
12549 namespace perfetto {
12550 namespace protos {
12551 namespace gen {
12552 enum ObservableEvents_Type : int {
12553   ObservableEvents_Type_TYPE_UNSPECIFIED = 0,
12554   ObservableEvents_Type_TYPE_DATA_SOURCES_INSTANCES = 1,
12555   ObservableEvents_Type_TYPE_ALL_DATA_SOURCES_STARTED = 2,
12556 };
12557 enum ObservableEvents_DataSourceInstanceState : int {
12558   ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STOPPED = 1,
12559   ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STARTED = 2,
12560 };
12561 
12562 class PERFETTO_EXPORT ObservableEvents : public ::protozero::CppMessageObj {
12563  public:
12564   using DataSourceInstanceStateChange = ObservableEvents_DataSourceInstanceStateChange;
12565   using Type = ObservableEvents_Type;
12566   static constexpr auto TYPE_UNSPECIFIED = ObservableEvents_Type_TYPE_UNSPECIFIED;
12567   static constexpr auto TYPE_DATA_SOURCES_INSTANCES = ObservableEvents_Type_TYPE_DATA_SOURCES_INSTANCES;
12568   static constexpr auto TYPE_ALL_DATA_SOURCES_STARTED = ObservableEvents_Type_TYPE_ALL_DATA_SOURCES_STARTED;
12569   static constexpr auto Type_MIN = ObservableEvents_Type_TYPE_UNSPECIFIED;
12570   static constexpr auto Type_MAX = ObservableEvents_Type_TYPE_ALL_DATA_SOURCES_STARTED;
12571   using DataSourceInstanceState = ObservableEvents_DataSourceInstanceState;
12572   static constexpr auto DATA_SOURCE_INSTANCE_STATE_STOPPED = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STOPPED;
12573   static constexpr auto DATA_SOURCE_INSTANCE_STATE_STARTED = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STARTED;
12574   static constexpr auto DataSourceInstanceState_MIN = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STOPPED;
12575   static constexpr auto DataSourceInstanceState_MAX = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STARTED;
12576   enum FieldNumbers {
12577     kInstanceStateChangesFieldNumber = 1,
12578     kAllDataSourcesStartedFieldNumber = 2,
12579   };
12580 
12581   ObservableEvents();
12582   ~ObservableEvents() override;
12583   ObservableEvents(ObservableEvents&&) noexcept;
12584   ObservableEvents& operator=(ObservableEvents&&);
12585   ObservableEvents(const ObservableEvents&);
12586   ObservableEvents& operator=(const ObservableEvents&);
12587   bool operator==(const ObservableEvents&) const;
operator !=(const ObservableEvents & other) const12588   bool operator!=(const ObservableEvents& other) const { return !(*this == other); }
12589 
12590   bool ParseFromArray(const void*, size_t) override;
12591   std::string SerializeAsString() const override;
12592   std::vector<uint8_t> SerializeAsArray() const override;
12593   void Serialize(::protozero::Message*) const;
12594 
instance_state_changes() const12595   const std::vector<ObservableEvents_DataSourceInstanceStateChange>& instance_state_changes() const { return instance_state_changes_; }
mutable_instance_state_changes()12596   std::vector<ObservableEvents_DataSourceInstanceStateChange>* mutable_instance_state_changes() { return &instance_state_changes_; }
12597   int instance_state_changes_size() const;
12598   void clear_instance_state_changes();
12599   ObservableEvents_DataSourceInstanceStateChange* add_instance_state_changes();
12600 
has_all_data_sources_started() const12601   bool has_all_data_sources_started() const { return _has_field_[2]; }
all_data_sources_started() const12602   bool all_data_sources_started() const { return all_data_sources_started_; }
set_all_data_sources_started(bool value)12603   void set_all_data_sources_started(bool value) { all_data_sources_started_ = value; _has_field_.set(2); }
12604 
12605  private:
12606   std::vector<ObservableEvents_DataSourceInstanceStateChange> instance_state_changes_;
12607   bool all_data_sources_started_{};
12608 
12609   // Allows to preserve unknown protobuf fields for compatibility
12610   // with future versions of .proto files.
12611   std::string unknown_fields_;
12612 
12613   std::bitset<3> _has_field_{};
12614 };
12615 
12616 
12617 class PERFETTO_EXPORT ObservableEvents_DataSourceInstanceStateChange : public ::protozero::CppMessageObj {
12618  public:
12619   enum FieldNumbers {
12620     kProducerNameFieldNumber = 1,
12621     kDataSourceNameFieldNumber = 2,
12622     kStateFieldNumber = 3,
12623   };
12624 
12625   ObservableEvents_DataSourceInstanceStateChange();
12626   ~ObservableEvents_DataSourceInstanceStateChange() override;
12627   ObservableEvents_DataSourceInstanceStateChange(ObservableEvents_DataSourceInstanceStateChange&&) noexcept;
12628   ObservableEvents_DataSourceInstanceStateChange& operator=(ObservableEvents_DataSourceInstanceStateChange&&);
12629   ObservableEvents_DataSourceInstanceStateChange(const ObservableEvents_DataSourceInstanceStateChange&);
12630   ObservableEvents_DataSourceInstanceStateChange& operator=(const ObservableEvents_DataSourceInstanceStateChange&);
12631   bool operator==(const ObservableEvents_DataSourceInstanceStateChange&) const;
operator !=(const ObservableEvents_DataSourceInstanceStateChange & other) const12632   bool operator!=(const ObservableEvents_DataSourceInstanceStateChange& other) const { return !(*this == other); }
12633 
12634   bool ParseFromArray(const void*, size_t) override;
12635   std::string SerializeAsString() const override;
12636   std::vector<uint8_t> SerializeAsArray() const override;
12637   void Serialize(::protozero::Message*) const;
12638 
has_producer_name() const12639   bool has_producer_name() const { return _has_field_[1]; }
producer_name() const12640   const std::string& producer_name() const { return producer_name_; }
set_producer_name(const std::string & value)12641   void set_producer_name(const std::string& value) { producer_name_ = value; _has_field_.set(1); }
12642 
has_data_source_name() const12643   bool has_data_source_name() const { return _has_field_[2]; }
data_source_name() const12644   const std::string& data_source_name() const { return data_source_name_; }
set_data_source_name(const std::string & value)12645   void set_data_source_name(const std::string& value) { data_source_name_ = value; _has_field_.set(2); }
12646 
has_state() const12647   bool has_state() const { return _has_field_[3]; }
state() const12648   ObservableEvents_DataSourceInstanceState state() const { return state_; }
set_state(ObservableEvents_DataSourceInstanceState value)12649   void set_state(ObservableEvents_DataSourceInstanceState value) { state_ = value; _has_field_.set(3); }
12650 
12651  private:
12652   std::string producer_name_{};
12653   std::string data_source_name_{};
12654   ObservableEvents_DataSourceInstanceState state_{};
12655 
12656   // Allows to preserve unknown protobuf fields for compatibility
12657   // with future versions of .proto files.
12658   std::string unknown_fields_;
12659 
12660   std::bitset<4> _has_field_{};
12661 };
12662 
12663 }  // namespace perfetto
12664 }  // namespace protos
12665 }  // namespace gen
12666 
12667 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_OBSERVABLE_EVENTS_PROTO_CPP_H_
12668 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
12669 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
12670 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
12671 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
12672 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
12673 #if defined(__GNUC__) || defined(__clang__)
12674 #pragma GCC diagnostic push
12675 #pragma GCC diagnostic ignored "-Wfloat-equal"
12676 #endif
12677 // gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"
12678 
12679 namespace perfetto {
12680 namespace protos {
12681 namespace gen {
12682 
12683 ObservableEvents::ObservableEvents() = default;
12684 ObservableEvents::~ObservableEvents() = default;
12685 ObservableEvents::ObservableEvents(const ObservableEvents&) = default;
12686 ObservableEvents& ObservableEvents::operator=(const ObservableEvents&) = default;
12687 ObservableEvents::ObservableEvents(ObservableEvents&&) noexcept = default;
12688 ObservableEvents& ObservableEvents::operator=(ObservableEvents&&) = default;
12689 
operator ==(const ObservableEvents & other) const12690 bool ObservableEvents::operator==(const ObservableEvents& other) const {
12691   return unknown_fields_ == other.unknown_fields_
12692    && instance_state_changes_ == other.instance_state_changes_
12693    && all_data_sources_started_ == other.all_data_sources_started_;
12694 }
12695 
instance_state_changes_size() const12696 int ObservableEvents::instance_state_changes_size() const { return static_cast<int>(instance_state_changes_.size()); }
clear_instance_state_changes()12697 void ObservableEvents::clear_instance_state_changes() { instance_state_changes_.clear(); }
add_instance_state_changes()12698 ObservableEvents_DataSourceInstanceStateChange* ObservableEvents::add_instance_state_changes() { instance_state_changes_.emplace_back(); return &instance_state_changes_.back(); }
ParseFromArray(const void * raw,size_t size)12699 bool ObservableEvents::ParseFromArray(const void* raw, size_t size) {
12700   instance_state_changes_.clear();
12701   unknown_fields_.clear();
12702   bool packed_error = false;
12703 
12704   ::protozero::ProtoDecoder dec(raw, size);
12705   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
12706     if (field.id() < _has_field_.size()) {
12707       _has_field_.set(field.id());
12708     }
12709     switch (field.id()) {
12710       case 1 /* instance_state_changes */:
12711         instance_state_changes_.emplace_back();
12712         instance_state_changes_.back().ParseFromArray(field.data(), field.size());
12713         break;
12714       case 2 /* all_data_sources_started */:
12715         field.get(&all_data_sources_started_);
12716         break;
12717       default:
12718         field.SerializeAndAppendTo(&unknown_fields_);
12719         break;
12720     }
12721   }
12722   return !packed_error && !dec.bytes_left();
12723 }
12724 
SerializeAsString() const12725 std::string ObservableEvents::SerializeAsString() const {
12726   ::protozero::HeapBuffered<::protozero::Message> msg;
12727   Serialize(msg.get());
12728   return msg.SerializeAsString();
12729 }
12730 
SerializeAsArray() const12731 std::vector<uint8_t> ObservableEvents::SerializeAsArray() const {
12732   ::protozero::HeapBuffered<::protozero::Message> msg;
12733   Serialize(msg.get());
12734   return msg.SerializeAsArray();
12735 }
12736 
Serialize(::protozero::Message * msg) const12737 void ObservableEvents::Serialize(::protozero::Message* msg) const {
12738   // Field 1: instance_state_changes
12739   for (auto& it : instance_state_changes_) {
12740     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
12741   }
12742 
12743   // Field 2: all_data_sources_started
12744   if (_has_field_[2]) {
12745     msg->AppendTinyVarInt(2, all_data_sources_started_);
12746   }
12747 
12748   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
12749 }
12750 
12751 
12752 ObservableEvents_DataSourceInstanceStateChange::ObservableEvents_DataSourceInstanceStateChange() = default;
12753 ObservableEvents_DataSourceInstanceStateChange::~ObservableEvents_DataSourceInstanceStateChange() = default;
12754 ObservableEvents_DataSourceInstanceStateChange::ObservableEvents_DataSourceInstanceStateChange(const ObservableEvents_DataSourceInstanceStateChange&) = default;
12755 ObservableEvents_DataSourceInstanceStateChange& ObservableEvents_DataSourceInstanceStateChange::operator=(const ObservableEvents_DataSourceInstanceStateChange&) = default;
12756 ObservableEvents_DataSourceInstanceStateChange::ObservableEvents_DataSourceInstanceStateChange(ObservableEvents_DataSourceInstanceStateChange&&) noexcept = default;
12757 ObservableEvents_DataSourceInstanceStateChange& ObservableEvents_DataSourceInstanceStateChange::operator=(ObservableEvents_DataSourceInstanceStateChange&&) = default;
12758 
operator ==(const ObservableEvents_DataSourceInstanceStateChange & other) const12759 bool ObservableEvents_DataSourceInstanceStateChange::operator==(const ObservableEvents_DataSourceInstanceStateChange& other) const {
12760   return unknown_fields_ == other.unknown_fields_
12761    && producer_name_ == other.producer_name_
12762    && data_source_name_ == other.data_source_name_
12763    && state_ == other.state_;
12764 }
12765 
ParseFromArray(const void * raw,size_t size)12766 bool ObservableEvents_DataSourceInstanceStateChange::ParseFromArray(const void* raw, size_t size) {
12767   unknown_fields_.clear();
12768   bool packed_error = false;
12769 
12770   ::protozero::ProtoDecoder dec(raw, size);
12771   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
12772     if (field.id() < _has_field_.size()) {
12773       _has_field_.set(field.id());
12774     }
12775     switch (field.id()) {
12776       case 1 /* producer_name */:
12777         field.get(&producer_name_);
12778         break;
12779       case 2 /* data_source_name */:
12780         field.get(&data_source_name_);
12781         break;
12782       case 3 /* state */:
12783         field.get(&state_);
12784         break;
12785       default:
12786         field.SerializeAndAppendTo(&unknown_fields_);
12787         break;
12788     }
12789   }
12790   return !packed_error && !dec.bytes_left();
12791 }
12792 
SerializeAsString() const12793 std::string ObservableEvents_DataSourceInstanceStateChange::SerializeAsString() const {
12794   ::protozero::HeapBuffered<::protozero::Message> msg;
12795   Serialize(msg.get());
12796   return msg.SerializeAsString();
12797 }
12798 
SerializeAsArray() const12799 std::vector<uint8_t> ObservableEvents_DataSourceInstanceStateChange::SerializeAsArray() const {
12800   ::protozero::HeapBuffered<::protozero::Message> msg;
12801   Serialize(msg.get());
12802   return msg.SerializeAsArray();
12803 }
12804 
Serialize(::protozero::Message * msg) const12805 void ObservableEvents_DataSourceInstanceStateChange::Serialize(::protozero::Message* msg) const {
12806   // Field 1: producer_name
12807   if (_has_field_[1]) {
12808     msg->AppendString(1, producer_name_);
12809   }
12810 
12811   // Field 2: data_source_name
12812   if (_has_field_[2]) {
12813     msg->AppendString(2, data_source_name_);
12814   }
12815 
12816   // Field 3: state
12817   if (_has_field_[3]) {
12818     msg->AppendVarInt(3, state_);
12819   }
12820 
12821   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
12822 }
12823 
12824 }  // namespace perfetto
12825 }  // namespace protos
12826 }  // namespace gen
12827 #if defined(__GNUC__) || defined(__clang__)
12828 #pragma GCC diagnostic pop
12829 #endif
12830 // gen_amalgamated begin source: gen/protos/perfetto/common/perf_events.gen.cc
12831 // gen_amalgamated begin header: gen/protos/perfetto/common/perf_events.gen.h
12832 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
12833 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_PERF_EVENTS_PROTO_CPP_H_
12834 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_PERF_EVENTS_PROTO_CPP_H_
12835 
12836 #include <stdint.h>
12837 #include <bitset>
12838 #include <vector>
12839 #include <string>
12840 #include <type_traits>
12841 
12842 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
12843 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
12844 // gen_amalgamated expanded: #include "perfetto/base/export.h"
12845 
12846 namespace perfetto {
12847 namespace protos {
12848 namespace gen {
12849 class PerfEvents;
12850 class PerfEvents_Tracepoint;
12851 class PerfEvents_Timebase;
12852 enum PerfEvents_Counter : int;
12853 }  // namespace perfetto
12854 }  // namespace protos
12855 }  // namespace gen
12856 
12857 namespace protozero {
12858 class Message;
12859 }  // namespace protozero
12860 
12861 namespace perfetto {
12862 namespace protos {
12863 namespace gen {
12864 enum PerfEvents_Counter : int {
12865   PerfEvents_Counter_UNKNOWN_COUNTER = 0,
12866   PerfEvents_Counter_SW_CPU_CLOCK = 1,
12867   PerfEvents_Counter_SW_PAGE_FAULTS = 2,
12868   PerfEvents_Counter_HW_CPU_CYCLES = 10,
12869   PerfEvents_Counter_HW_INSTRUCTIONS = 11,
12870 };
12871 
12872 class PERFETTO_EXPORT PerfEvents : public ::protozero::CppMessageObj {
12873  public:
12874   using Timebase = PerfEvents_Timebase;
12875   using Tracepoint = PerfEvents_Tracepoint;
12876   using Counter = PerfEvents_Counter;
12877   static constexpr auto UNKNOWN_COUNTER = PerfEvents_Counter_UNKNOWN_COUNTER;
12878   static constexpr auto SW_CPU_CLOCK = PerfEvents_Counter_SW_CPU_CLOCK;
12879   static constexpr auto SW_PAGE_FAULTS = PerfEvents_Counter_SW_PAGE_FAULTS;
12880   static constexpr auto HW_CPU_CYCLES = PerfEvents_Counter_HW_CPU_CYCLES;
12881   static constexpr auto HW_INSTRUCTIONS = PerfEvents_Counter_HW_INSTRUCTIONS;
12882   static constexpr auto Counter_MIN = PerfEvents_Counter_UNKNOWN_COUNTER;
12883   static constexpr auto Counter_MAX = PerfEvents_Counter_HW_INSTRUCTIONS;
12884   enum FieldNumbers {
12885   };
12886 
12887   PerfEvents();
12888   ~PerfEvents() override;
12889   PerfEvents(PerfEvents&&) noexcept;
12890   PerfEvents& operator=(PerfEvents&&);
12891   PerfEvents(const PerfEvents&);
12892   PerfEvents& operator=(const PerfEvents&);
12893   bool operator==(const PerfEvents&) const;
operator !=(const PerfEvents & other) const12894   bool operator!=(const PerfEvents& other) const { return !(*this == other); }
12895 
12896   bool ParseFromArray(const void*, size_t) override;
12897   std::string SerializeAsString() const override;
12898   std::vector<uint8_t> SerializeAsArray() const override;
12899   void Serialize(::protozero::Message*) const;
12900 
12901  private:
12902 
12903   // Allows to preserve unknown protobuf fields for compatibility
12904   // with future versions of .proto files.
12905   std::string unknown_fields_;
12906 
12907   std::bitset<2> _has_field_{};
12908 };
12909 
12910 
12911 class PERFETTO_EXPORT PerfEvents_Tracepoint : public ::protozero::CppMessageObj {
12912  public:
12913   enum FieldNumbers {
12914     kNameFieldNumber = 1,
12915     kFilterFieldNumber = 2,
12916   };
12917 
12918   PerfEvents_Tracepoint();
12919   ~PerfEvents_Tracepoint() override;
12920   PerfEvents_Tracepoint(PerfEvents_Tracepoint&&) noexcept;
12921   PerfEvents_Tracepoint& operator=(PerfEvents_Tracepoint&&);
12922   PerfEvents_Tracepoint(const PerfEvents_Tracepoint&);
12923   PerfEvents_Tracepoint& operator=(const PerfEvents_Tracepoint&);
12924   bool operator==(const PerfEvents_Tracepoint&) const;
operator !=(const PerfEvents_Tracepoint & other) const12925   bool operator!=(const PerfEvents_Tracepoint& other) const { return !(*this == other); }
12926 
12927   bool ParseFromArray(const void*, size_t) override;
12928   std::string SerializeAsString() const override;
12929   std::vector<uint8_t> SerializeAsArray() const override;
12930   void Serialize(::protozero::Message*) const;
12931 
has_name() const12932   bool has_name() const { return _has_field_[1]; }
name() const12933   const std::string& name() const { return name_; }
set_name(const std::string & value)12934   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
12935 
has_filter() const12936   bool has_filter() const { return _has_field_[2]; }
filter() const12937   const std::string& filter() const { return filter_; }
set_filter(const std::string & value)12938   void set_filter(const std::string& value) { filter_ = value; _has_field_.set(2); }
12939 
12940  private:
12941   std::string name_{};
12942   std::string filter_{};
12943 
12944   // Allows to preserve unknown protobuf fields for compatibility
12945   // with future versions of .proto files.
12946   std::string unknown_fields_;
12947 
12948   std::bitset<3> _has_field_{};
12949 };
12950 
12951 
12952 class PERFETTO_EXPORT PerfEvents_Timebase : public ::protozero::CppMessageObj {
12953  public:
12954   enum FieldNumbers {
12955     kFrequencyFieldNumber = 2,
12956     kPeriodFieldNumber = 1,
12957     kCounterFieldNumber = 4,
12958     kTracepointFieldNumber = 3,
12959   };
12960 
12961   PerfEvents_Timebase();
12962   ~PerfEvents_Timebase() override;
12963   PerfEvents_Timebase(PerfEvents_Timebase&&) noexcept;
12964   PerfEvents_Timebase& operator=(PerfEvents_Timebase&&);
12965   PerfEvents_Timebase(const PerfEvents_Timebase&);
12966   PerfEvents_Timebase& operator=(const PerfEvents_Timebase&);
12967   bool operator==(const PerfEvents_Timebase&) const;
operator !=(const PerfEvents_Timebase & other) const12968   bool operator!=(const PerfEvents_Timebase& other) const { return !(*this == other); }
12969 
12970   bool ParseFromArray(const void*, size_t) override;
12971   std::string SerializeAsString() const override;
12972   std::vector<uint8_t> SerializeAsArray() const override;
12973   void Serialize(::protozero::Message*) const;
12974 
has_frequency() const12975   bool has_frequency() const { return _has_field_[2]; }
frequency() const12976   uint64_t frequency() const { return frequency_; }
set_frequency(uint64_t value)12977   void set_frequency(uint64_t value) { frequency_ = value; _has_field_.set(2); }
12978 
has_period() const12979   bool has_period() const { return _has_field_[1]; }
period() const12980   uint64_t period() const { return period_; }
set_period(uint64_t value)12981   void set_period(uint64_t value) { period_ = value; _has_field_.set(1); }
12982 
has_counter() const12983   bool has_counter() const { return _has_field_[4]; }
counter() const12984   PerfEvents_Counter counter() const { return counter_; }
set_counter(PerfEvents_Counter value)12985   void set_counter(PerfEvents_Counter value) { counter_ = value; _has_field_.set(4); }
12986 
has_tracepoint() const12987   bool has_tracepoint() const { return _has_field_[3]; }
tracepoint() const12988   const PerfEvents_Tracepoint& tracepoint() const { return *tracepoint_; }
mutable_tracepoint()12989   PerfEvents_Tracepoint* mutable_tracepoint() { _has_field_.set(3); return tracepoint_.get(); }
12990 
12991  private:
12992   uint64_t frequency_{};
12993   uint64_t period_{};
12994   PerfEvents_Counter counter_{};
12995   ::protozero::CopyablePtr<PerfEvents_Tracepoint> tracepoint_;
12996 
12997   // Allows to preserve unknown protobuf fields for compatibility
12998   // with future versions of .proto files.
12999   std::string unknown_fields_;
13000 
13001   std::bitset<5> _has_field_{};
13002 };
13003 
13004 }  // namespace perfetto
13005 }  // namespace protos
13006 }  // namespace gen
13007 
13008 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_PERF_EVENTS_PROTO_CPP_H_
13009 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
13010 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
13011 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
13012 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
13013 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
13014 #if defined(__GNUC__) || defined(__clang__)
13015 #pragma GCC diagnostic push
13016 #pragma GCC diagnostic ignored "-Wfloat-equal"
13017 #endif
13018 // gen_amalgamated expanded: #include "protos/perfetto/common/perf_events.gen.h"
13019 
13020 namespace perfetto {
13021 namespace protos {
13022 namespace gen {
13023 
13024 PerfEvents::PerfEvents() = default;
13025 PerfEvents::~PerfEvents() = default;
13026 PerfEvents::PerfEvents(const PerfEvents&) = default;
13027 PerfEvents& PerfEvents::operator=(const PerfEvents&) = default;
13028 PerfEvents::PerfEvents(PerfEvents&&) noexcept = default;
13029 PerfEvents& PerfEvents::operator=(PerfEvents&&) = default;
13030 
operator ==(const PerfEvents & other) const13031 bool PerfEvents::operator==(const PerfEvents& other) const {
13032   return unknown_fields_ == other.unknown_fields_;
13033 }
13034 
ParseFromArray(const void * raw,size_t size)13035 bool PerfEvents::ParseFromArray(const void* raw, size_t size) {
13036   unknown_fields_.clear();
13037   bool packed_error = false;
13038 
13039   ::protozero::ProtoDecoder dec(raw, size);
13040   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
13041     if (field.id() < _has_field_.size()) {
13042       _has_field_.set(field.id());
13043     }
13044     switch (field.id()) {
13045       default:
13046         field.SerializeAndAppendTo(&unknown_fields_);
13047         break;
13048     }
13049   }
13050   return !packed_error && !dec.bytes_left();
13051 }
13052 
SerializeAsString() const13053 std::string PerfEvents::SerializeAsString() const {
13054   ::protozero::HeapBuffered<::protozero::Message> msg;
13055   Serialize(msg.get());
13056   return msg.SerializeAsString();
13057 }
13058 
SerializeAsArray() const13059 std::vector<uint8_t> PerfEvents::SerializeAsArray() const {
13060   ::protozero::HeapBuffered<::protozero::Message> msg;
13061   Serialize(msg.get());
13062   return msg.SerializeAsArray();
13063 }
13064 
Serialize(::protozero::Message * msg) const13065 void PerfEvents::Serialize(::protozero::Message* msg) const {
13066   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
13067 }
13068 
13069 
13070 PerfEvents_Tracepoint::PerfEvents_Tracepoint() = default;
13071 PerfEvents_Tracepoint::~PerfEvents_Tracepoint() = default;
13072 PerfEvents_Tracepoint::PerfEvents_Tracepoint(const PerfEvents_Tracepoint&) = default;
13073 PerfEvents_Tracepoint& PerfEvents_Tracepoint::operator=(const PerfEvents_Tracepoint&) = default;
13074 PerfEvents_Tracepoint::PerfEvents_Tracepoint(PerfEvents_Tracepoint&&) noexcept = default;
13075 PerfEvents_Tracepoint& PerfEvents_Tracepoint::operator=(PerfEvents_Tracepoint&&) = default;
13076 
operator ==(const PerfEvents_Tracepoint & other) const13077 bool PerfEvents_Tracepoint::operator==(const PerfEvents_Tracepoint& other) const {
13078   return unknown_fields_ == other.unknown_fields_
13079    && name_ == other.name_
13080    && filter_ == other.filter_;
13081 }
13082 
ParseFromArray(const void * raw,size_t size)13083 bool PerfEvents_Tracepoint::ParseFromArray(const void* raw, size_t size) {
13084   unknown_fields_.clear();
13085   bool packed_error = false;
13086 
13087   ::protozero::ProtoDecoder dec(raw, size);
13088   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
13089     if (field.id() < _has_field_.size()) {
13090       _has_field_.set(field.id());
13091     }
13092     switch (field.id()) {
13093       case 1 /* name */:
13094         field.get(&name_);
13095         break;
13096       case 2 /* filter */:
13097         field.get(&filter_);
13098         break;
13099       default:
13100         field.SerializeAndAppendTo(&unknown_fields_);
13101         break;
13102     }
13103   }
13104   return !packed_error && !dec.bytes_left();
13105 }
13106 
SerializeAsString() const13107 std::string PerfEvents_Tracepoint::SerializeAsString() const {
13108   ::protozero::HeapBuffered<::protozero::Message> msg;
13109   Serialize(msg.get());
13110   return msg.SerializeAsString();
13111 }
13112 
SerializeAsArray() const13113 std::vector<uint8_t> PerfEvents_Tracepoint::SerializeAsArray() const {
13114   ::protozero::HeapBuffered<::protozero::Message> msg;
13115   Serialize(msg.get());
13116   return msg.SerializeAsArray();
13117 }
13118 
Serialize(::protozero::Message * msg) const13119 void PerfEvents_Tracepoint::Serialize(::protozero::Message* msg) const {
13120   // Field 1: name
13121   if (_has_field_[1]) {
13122     msg->AppendString(1, name_);
13123   }
13124 
13125   // Field 2: filter
13126   if (_has_field_[2]) {
13127     msg->AppendString(2, filter_);
13128   }
13129 
13130   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
13131 }
13132 
13133 
13134 PerfEvents_Timebase::PerfEvents_Timebase() = default;
13135 PerfEvents_Timebase::~PerfEvents_Timebase() = default;
13136 PerfEvents_Timebase::PerfEvents_Timebase(const PerfEvents_Timebase&) = default;
13137 PerfEvents_Timebase& PerfEvents_Timebase::operator=(const PerfEvents_Timebase&) = default;
13138 PerfEvents_Timebase::PerfEvents_Timebase(PerfEvents_Timebase&&) noexcept = default;
13139 PerfEvents_Timebase& PerfEvents_Timebase::operator=(PerfEvents_Timebase&&) = default;
13140 
operator ==(const PerfEvents_Timebase & other) const13141 bool PerfEvents_Timebase::operator==(const PerfEvents_Timebase& other) const {
13142   return unknown_fields_ == other.unknown_fields_
13143    && frequency_ == other.frequency_
13144    && period_ == other.period_
13145    && counter_ == other.counter_
13146    && tracepoint_ == other.tracepoint_;
13147 }
13148 
ParseFromArray(const void * raw,size_t size)13149 bool PerfEvents_Timebase::ParseFromArray(const void* raw, size_t size) {
13150   unknown_fields_.clear();
13151   bool packed_error = false;
13152 
13153   ::protozero::ProtoDecoder dec(raw, size);
13154   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
13155     if (field.id() < _has_field_.size()) {
13156       _has_field_.set(field.id());
13157     }
13158     switch (field.id()) {
13159       case 2 /* frequency */:
13160         field.get(&frequency_);
13161         break;
13162       case 1 /* period */:
13163         field.get(&period_);
13164         break;
13165       case 4 /* counter */:
13166         field.get(&counter_);
13167         break;
13168       case 3 /* tracepoint */:
13169         (*tracepoint_).ParseFromArray(field.data(), field.size());
13170         break;
13171       default:
13172         field.SerializeAndAppendTo(&unknown_fields_);
13173         break;
13174     }
13175   }
13176   return !packed_error && !dec.bytes_left();
13177 }
13178 
SerializeAsString() const13179 std::string PerfEvents_Timebase::SerializeAsString() const {
13180   ::protozero::HeapBuffered<::protozero::Message> msg;
13181   Serialize(msg.get());
13182   return msg.SerializeAsString();
13183 }
13184 
SerializeAsArray() const13185 std::vector<uint8_t> PerfEvents_Timebase::SerializeAsArray() const {
13186   ::protozero::HeapBuffered<::protozero::Message> msg;
13187   Serialize(msg.get());
13188   return msg.SerializeAsArray();
13189 }
13190 
Serialize(::protozero::Message * msg) const13191 void PerfEvents_Timebase::Serialize(::protozero::Message* msg) const {
13192   // Field 2: frequency
13193   if (_has_field_[2]) {
13194     msg->AppendVarInt(2, frequency_);
13195   }
13196 
13197   // Field 1: period
13198   if (_has_field_[1]) {
13199     msg->AppendVarInt(1, period_);
13200   }
13201 
13202   // Field 4: counter
13203   if (_has_field_[4]) {
13204     msg->AppendVarInt(4, counter_);
13205   }
13206 
13207   // Field 3: tracepoint
13208   if (_has_field_[3]) {
13209     (*tracepoint_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
13210   }
13211 
13212   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
13213 }
13214 
13215 }  // namespace perfetto
13216 }  // namespace protos
13217 }  // namespace gen
13218 #if defined(__GNUC__) || defined(__clang__)
13219 #pragma GCC diagnostic pop
13220 #endif
13221 // gen_amalgamated begin source: gen/protos/perfetto/common/sys_stats_counters.gen.cc
13222 // gen_amalgamated begin header: gen/protos/perfetto/common/sys_stats_counters.gen.h
13223 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
13224 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_SYS_STATS_COUNTERS_PROTO_CPP_H_
13225 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_SYS_STATS_COUNTERS_PROTO_CPP_H_
13226 
13227 #include <stdint.h>
13228 #include <bitset>
13229 #include <vector>
13230 #include <string>
13231 #include <type_traits>
13232 
13233 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
13234 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
13235 // gen_amalgamated expanded: #include "perfetto/base/export.h"
13236 
13237 namespace perfetto {
13238 namespace protos {
13239 namespace gen {
13240 enum MeminfoCounters : int;
13241 enum VmstatCounters : int;
13242 }  // namespace perfetto
13243 }  // namespace protos
13244 }  // namespace gen
13245 
13246 namespace protozero {
13247 class Message;
13248 }  // namespace protozero
13249 
13250 namespace perfetto {
13251 namespace protos {
13252 namespace gen {
13253 enum MeminfoCounters : int {
13254   MEMINFO_UNSPECIFIED = 0,
13255   MEMINFO_MEM_TOTAL = 1,
13256   MEMINFO_MEM_FREE = 2,
13257   MEMINFO_MEM_AVAILABLE = 3,
13258   MEMINFO_BUFFERS = 4,
13259   MEMINFO_CACHED = 5,
13260   MEMINFO_SWAP_CACHED = 6,
13261   MEMINFO_ACTIVE = 7,
13262   MEMINFO_INACTIVE = 8,
13263   MEMINFO_ACTIVE_ANON = 9,
13264   MEMINFO_INACTIVE_ANON = 10,
13265   MEMINFO_ACTIVE_FILE = 11,
13266   MEMINFO_INACTIVE_FILE = 12,
13267   MEMINFO_UNEVICTABLE = 13,
13268   MEMINFO_MLOCKED = 14,
13269   MEMINFO_SWAP_TOTAL = 15,
13270   MEMINFO_SWAP_FREE = 16,
13271   MEMINFO_DIRTY = 17,
13272   MEMINFO_WRITEBACK = 18,
13273   MEMINFO_ANON_PAGES = 19,
13274   MEMINFO_MAPPED = 20,
13275   MEMINFO_SHMEM = 21,
13276   MEMINFO_SLAB = 22,
13277   MEMINFO_SLAB_RECLAIMABLE = 23,
13278   MEMINFO_SLAB_UNRECLAIMABLE = 24,
13279   MEMINFO_KERNEL_STACK = 25,
13280   MEMINFO_PAGE_TABLES = 26,
13281   MEMINFO_COMMIT_LIMIT = 27,
13282   MEMINFO_COMMITED_AS = 28,
13283   MEMINFO_VMALLOC_TOTAL = 29,
13284   MEMINFO_VMALLOC_USED = 30,
13285   MEMINFO_VMALLOC_CHUNK = 31,
13286   MEMINFO_CMA_TOTAL = 32,
13287   MEMINFO_CMA_FREE = 33,
13288 };
13289 enum VmstatCounters : int {
13290   VMSTAT_UNSPECIFIED = 0,
13291   VMSTAT_NR_FREE_PAGES = 1,
13292   VMSTAT_NR_ALLOC_BATCH = 2,
13293   VMSTAT_NR_INACTIVE_ANON = 3,
13294   VMSTAT_NR_ACTIVE_ANON = 4,
13295   VMSTAT_NR_INACTIVE_FILE = 5,
13296   VMSTAT_NR_ACTIVE_FILE = 6,
13297   VMSTAT_NR_UNEVICTABLE = 7,
13298   VMSTAT_NR_MLOCK = 8,
13299   VMSTAT_NR_ANON_PAGES = 9,
13300   VMSTAT_NR_MAPPED = 10,
13301   VMSTAT_NR_FILE_PAGES = 11,
13302   VMSTAT_NR_DIRTY = 12,
13303   VMSTAT_NR_WRITEBACK = 13,
13304   VMSTAT_NR_SLAB_RECLAIMABLE = 14,
13305   VMSTAT_NR_SLAB_UNRECLAIMABLE = 15,
13306   VMSTAT_NR_PAGE_TABLE_PAGES = 16,
13307   VMSTAT_NR_KERNEL_STACK = 17,
13308   VMSTAT_NR_OVERHEAD = 18,
13309   VMSTAT_NR_UNSTABLE = 19,
13310   VMSTAT_NR_BOUNCE = 20,
13311   VMSTAT_NR_VMSCAN_WRITE = 21,
13312   VMSTAT_NR_VMSCAN_IMMEDIATE_RECLAIM = 22,
13313   VMSTAT_NR_WRITEBACK_TEMP = 23,
13314   VMSTAT_NR_ISOLATED_ANON = 24,
13315   VMSTAT_NR_ISOLATED_FILE = 25,
13316   VMSTAT_NR_SHMEM = 26,
13317   VMSTAT_NR_DIRTIED = 27,
13318   VMSTAT_NR_WRITTEN = 28,
13319   VMSTAT_NR_PAGES_SCANNED = 29,
13320   VMSTAT_WORKINGSET_REFAULT = 30,
13321   VMSTAT_WORKINGSET_ACTIVATE = 31,
13322   VMSTAT_WORKINGSET_NODERECLAIM = 32,
13323   VMSTAT_NR_ANON_TRANSPARENT_HUGEPAGES = 33,
13324   VMSTAT_NR_FREE_CMA = 34,
13325   VMSTAT_NR_SWAPCACHE = 35,
13326   VMSTAT_NR_DIRTY_THRESHOLD = 36,
13327   VMSTAT_NR_DIRTY_BACKGROUND_THRESHOLD = 37,
13328   VMSTAT_PGPGIN = 38,
13329   VMSTAT_PGPGOUT = 39,
13330   VMSTAT_PGPGOUTCLEAN = 40,
13331   VMSTAT_PSWPIN = 41,
13332   VMSTAT_PSWPOUT = 42,
13333   VMSTAT_PGALLOC_DMA = 43,
13334   VMSTAT_PGALLOC_NORMAL = 44,
13335   VMSTAT_PGALLOC_MOVABLE = 45,
13336   VMSTAT_PGFREE = 46,
13337   VMSTAT_PGACTIVATE = 47,
13338   VMSTAT_PGDEACTIVATE = 48,
13339   VMSTAT_PGFAULT = 49,
13340   VMSTAT_PGMAJFAULT = 50,
13341   VMSTAT_PGREFILL_DMA = 51,
13342   VMSTAT_PGREFILL_NORMAL = 52,
13343   VMSTAT_PGREFILL_MOVABLE = 53,
13344   VMSTAT_PGSTEAL_KSWAPD_DMA = 54,
13345   VMSTAT_PGSTEAL_KSWAPD_NORMAL = 55,
13346   VMSTAT_PGSTEAL_KSWAPD_MOVABLE = 56,
13347   VMSTAT_PGSTEAL_DIRECT_DMA = 57,
13348   VMSTAT_PGSTEAL_DIRECT_NORMAL = 58,
13349   VMSTAT_PGSTEAL_DIRECT_MOVABLE = 59,
13350   VMSTAT_PGSCAN_KSWAPD_DMA = 60,
13351   VMSTAT_PGSCAN_KSWAPD_NORMAL = 61,
13352   VMSTAT_PGSCAN_KSWAPD_MOVABLE = 62,
13353   VMSTAT_PGSCAN_DIRECT_DMA = 63,
13354   VMSTAT_PGSCAN_DIRECT_NORMAL = 64,
13355   VMSTAT_PGSCAN_DIRECT_MOVABLE = 65,
13356   VMSTAT_PGSCAN_DIRECT_THROTTLE = 66,
13357   VMSTAT_PGINODESTEAL = 67,
13358   VMSTAT_SLABS_SCANNED = 68,
13359   VMSTAT_KSWAPD_INODESTEAL = 69,
13360   VMSTAT_KSWAPD_LOW_WMARK_HIT_QUICKLY = 70,
13361   VMSTAT_KSWAPD_HIGH_WMARK_HIT_QUICKLY = 71,
13362   VMSTAT_PAGEOUTRUN = 72,
13363   VMSTAT_ALLOCSTALL = 73,
13364   VMSTAT_PGROTATED = 74,
13365   VMSTAT_DROP_PAGECACHE = 75,
13366   VMSTAT_DROP_SLAB = 76,
13367   VMSTAT_PGMIGRATE_SUCCESS = 77,
13368   VMSTAT_PGMIGRATE_FAIL = 78,
13369   VMSTAT_COMPACT_MIGRATE_SCANNED = 79,
13370   VMSTAT_COMPACT_FREE_SCANNED = 80,
13371   VMSTAT_COMPACT_ISOLATED = 81,
13372   VMSTAT_COMPACT_STALL = 82,
13373   VMSTAT_COMPACT_FAIL = 83,
13374   VMSTAT_COMPACT_SUCCESS = 84,
13375   VMSTAT_COMPACT_DAEMON_WAKE = 85,
13376   VMSTAT_UNEVICTABLE_PGS_CULLED = 86,
13377   VMSTAT_UNEVICTABLE_PGS_SCANNED = 87,
13378   VMSTAT_UNEVICTABLE_PGS_RESCUED = 88,
13379   VMSTAT_UNEVICTABLE_PGS_MLOCKED = 89,
13380   VMSTAT_UNEVICTABLE_PGS_MUNLOCKED = 90,
13381   VMSTAT_UNEVICTABLE_PGS_CLEARED = 91,
13382   VMSTAT_UNEVICTABLE_PGS_STRANDED = 92,
13383   VMSTAT_NR_ZSPAGES = 93,
13384   VMSTAT_NR_ION_HEAP = 94,
13385   VMSTAT_NR_GPU_HEAP = 95,
13386   VMSTAT_ALLOCSTALL_DMA = 96,
13387   VMSTAT_ALLOCSTALL_MOVABLE = 97,
13388   VMSTAT_ALLOCSTALL_NORMAL = 98,
13389   VMSTAT_COMPACT_DAEMON_FREE_SCANNED = 99,
13390   VMSTAT_COMPACT_DAEMON_MIGRATE_SCANNED = 100,
13391   VMSTAT_NR_FASTRPC = 101,
13392   VMSTAT_NR_INDIRECTLY_RECLAIMABLE = 102,
13393   VMSTAT_NR_ION_HEAP_POOL = 103,
13394   VMSTAT_NR_KERNEL_MISC_RECLAIMABLE = 104,
13395   VMSTAT_NR_SHADOW_CALL_STACK_BYTES = 105,
13396   VMSTAT_NR_SHMEM_HUGEPAGES = 106,
13397   VMSTAT_NR_SHMEM_PMDMAPPED = 107,
13398   VMSTAT_NR_UNRECLAIMABLE_PAGES = 108,
13399   VMSTAT_NR_ZONE_ACTIVE_ANON = 109,
13400   VMSTAT_NR_ZONE_ACTIVE_FILE = 110,
13401   VMSTAT_NR_ZONE_INACTIVE_ANON = 111,
13402   VMSTAT_NR_ZONE_INACTIVE_FILE = 112,
13403   VMSTAT_NR_ZONE_UNEVICTABLE = 113,
13404   VMSTAT_NR_ZONE_WRITE_PENDING = 114,
13405   VMSTAT_OOM_KILL = 115,
13406   VMSTAT_PGLAZYFREE = 116,
13407   VMSTAT_PGLAZYFREED = 117,
13408   VMSTAT_PGREFILL = 118,
13409   VMSTAT_PGSCAN_DIRECT = 119,
13410   VMSTAT_PGSCAN_KSWAPD = 120,
13411   VMSTAT_PGSKIP_DMA = 121,
13412   VMSTAT_PGSKIP_MOVABLE = 122,
13413   VMSTAT_PGSKIP_NORMAL = 123,
13414   VMSTAT_PGSTEAL_DIRECT = 124,
13415   VMSTAT_PGSTEAL_KSWAPD = 125,
13416   VMSTAT_SWAP_RA = 126,
13417   VMSTAT_SWAP_RA_HIT = 127,
13418   VMSTAT_WORKINGSET_RESTORE = 128,
13419 };
13420 }  // namespace perfetto
13421 }  // namespace protos
13422 }  // namespace gen
13423 
13424 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_SYS_STATS_COUNTERS_PROTO_CPP_H_
13425 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
13426 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
13427 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
13428 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
13429 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
13430 #if defined(__GNUC__) || defined(__clang__)
13431 #pragma GCC diagnostic push
13432 #pragma GCC diagnostic ignored "-Wfloat-equal"
13433 #endif
13434 // gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
13435 
13436 namespace perfetto {
13437 namespace protos {
13438 namespace gen {
13439 }  // namespace perfetto
13440 }  // namespace protos
13441 }  // namespace gen
13442 #if defined(__GNUC__) || defined(__clang__)
13443 #pragma GCC diagnostic pop
13444 #endif
13445 // gen_amalgamated begin source: gen/protos/perfetto/common/trace_stats.gen.cc
13446 // gen_amalgamated begin header: gen/protos/perfetto/common/trace_stats.gen.h
13447 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
13448 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACE_STATS_PROTO_CPP_H_
13449 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACE_STATS_PROTO_CPP_H_
13450 
13451 #include <stdint.h>
13452 #include <bitset>
13453 #include <vector>
13454 #include <string>
13455 #include <type_traits>
13456 
13457 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
13458 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
13459 // gen_amalgamated expanded: #include "perfetto/base/export.h"
13460 
13461 namespace perfetto {
13462 namespace protos {
13463 namespace gen {
13464 class TraceStats;
13465 class TraceStats_FilterStats;
13466 class TraceStats_BufferStats;
13467 }  // namespace perfetto
13468 }  // namespace protos
13469 }  // namespace gen
13470 
13471 namespace protozero {
13472 class Message;
13473 }  // namespace protozero
13474 
13475 namespace perfetto {
13476 namespace protos {
13477 namespace gen {
13478 
13479 class PERFETTO_EXPORT TraceStats : public ::protozero::CppMessageObj {
13480  public:
13481   using BufferStats = TraceStats_BufferStats;
13482   using FilterStats = TraceStats_FilterStats;
13483   enum FieldNumbers {
13484     kBufferStatsFieldNumber = 1,
13485     kProducersConnectedFieldNumber = 2,
13486     kProducersSeenFieldNumber = 3,
13487     kDataSourcesRegisteredFieldNumber = 4,
13488     kDataSourcesSeenFieldNumber = 5,
13489     kTracingSessionsFieldNumber = 6,
13490     kTotalBuffersFieldNumber = 7,
13491     kChunksDiscardedFieldNumber = 8,
13492     kPatchesDiscardedFieldNumber = 9,
13493     kInvalidPacketsFieldNumber = 10,
13494     kFilterStatsFieldNumber = 11,
13495   };
13496 
13497   TraceStats();
13498   ~TraceStats() override;
13499   TraceStats(TraceStats&&) noexcept;
13500   TraceStats& operator=(TraceStats&&);
13501   TraceStats(const TraceStats&);
13502   TraceStats& operator=(const TraceStats&);
13503   bool operator==(const TraceStats&) const;
operator !=(const TraceStats & other) const13504   bool operator!=(const TraceStats& other) const { return !(*this == other); }
13505 
13506   bool ParseFromArray(const void*, size_t) override;
13507   std::string SerializeAsString() const override;
13508   std::vector<uint8_t> SerializeAsArray() const override;
13509   void Serialize(::protozero::Message*) const;
13510 
buffer_stats() const13511   const std::vector<TraceStats_BufferStats>& buffer_stats() const { return buffer_stats_; }
mutable_buffer_stats()13512   std::vector<TraceStats_BufferStats>* mutable_buffer_stats() { return &buffer_stats_; }
13513   int buffer_stats_size() const;
13514   void clear_buffer_stats();
13515   TraceStats_BufferStats* add_buffer_stats();
13516 
has_producers_connected() const13517   bool has_producers_connected() const { return _has_field_[2]; }
producers_connected() const13518   uint32_t producers_connected() const { return producers_connected_; }
set_producers_connected(uint32_t value)13519   void set_producers_connected(uint32_t value) { producers_connected_ = value; _has_field_.set(2); }
13520 
has_producers_seen() const13521   bool has_producers_seen() const { return _has_field_[3]; }
producers_seen() const13522   uint64_t producers_seen() const { return producers_seen_; }
set_producers_seen(uint64_t value)13523   void set_producers_seen(uint64_t value) { producers_seen_ = value; _has_field_.set(3); }
13524 
has_data_sources_registered() const13525   bool has_data_sources_registered() const { return _has_field_[4]; }
data_sources_registered() const13526   uint32_t data_sources_registered() const { return data_sources_registered_; }
set_data_sources_registered(uint32_t value)13527   void set_data_sources_registered(uint32_t value) { data_sources_registered_ = value; _has_field_.set(4); }
13528 
has_data_sources_seen() const13529   bool has_data_sources_seen() const { return _has_field_[5]; }
data_sources_seen() const13530   uint64_t data_sources_seen() const { return data_sources_seen_; }
set_data_sources_seen(uint64_t value)13531   void set_data_sources_seen(uint64_t value) { data_sources_seen_ = value; _has_field_.set(5); }
13532 
has_tracing_sessions() const13533   bool has_tracing_sessions() const { return _has_field_[6]; }
tracing_sessions() const13534   uint32_t tracing_sessions() const { return tracing_sessions_; }
set_tracing_sessions(uint32_t value)13535   void set_tracing_sessions(uint32_t value) { tracing_sessions_ = value; _has_field_.set(6); }
13536 
has_total_buffers() const13537   bool has_total_buffers() const { return _has_field_[7]; }
total_buffers() const13538   uint32_t total_buffers() const { return total_buffers_; }
set_total_buffers(uint32_t value)13539   void set_total_buffers(uint32_t value) { total_buffers_ = value; _has_field_.set(7); }
13540 
has_chunks_discarded() const13541   bool has_chunks_discarded() const { return _has_field_[8]; }
chunks_discarded() const13542   uint64_t chunks_discarded() const { return chunks_discarded_; }
set_chunks_discarded(uint64_t value)13543   void set_chunks_discarded(uint64_t value) { chunks_discarded_ = value; _has_field_.set(8); }
13544 
has_patches_discarded() const13545   bool has_patches_discarded() const { return _has_field_[9]; }
patches_discarded() const13546   uint64_t patches_discarded() const { return patches_discarded_; }
set_patches_discarded(uint64_t value)13547   void set_patches_discarded(uint64_t value) { patches_discarded_ = value; _has_field_.set(9); }
13548 
has_invalid_packets() const13549   bool has_invalid_packets() const { return _has_field_[10]; }
invalid_packets() const13550   uint64_t invalid_packets() const { return invalid_packets_; }
set_invalid_packets(uint64_t value)13551   void set_invalid_packets(uint64_t value) { invalid_packets_ = value; _has_field_.set(10); }
13552 
has_filter_stats() const13553   bool has_filter_stats() const { return _has_field_[11]; }
filter_stats() const13554   const TraceStats_FilterStats& filter_stats() const { return *filter_stats_; }
mutable_filter_stats()13555   TraceStats_FilterStats* mutable_filter_stats() { _has_field_.set(11); return filter_stats_.get(); }
13556 
13557  private:
13558   std::vector<TraceStats_BufferStats> buffer_stats_;
13559   uint32_t producers_connected_{};
13560   uint64_t producers_seen_{};
13561   uint32_t data_sources_registered_{};
13562   uint64_t data_sources_seen_{};
13563   uint32_t tracing_sessions_{};
13564   uint32_t total_buffers_{};
13565   uint64_t chunks_discarded_{};
13566   uint64_t patches_discarded_{};
13567   uint64_t invalid_packets_{};
13568   ::protozero::CopyablePtr<TraceStats_FilterStats> filter_stats_;
13569 
13570   // Allows to preserve unknown protobuf fields for compatibility
13571   // with future versions of .proto files.
13572   std::string unknown_fields_;
13573 
13574   std::bitset<12> _has_field_{};
13575 };
13576 
13577 
13578 class PERFETTO_EXPORT TraceStats_FilterStats : public ::protozero::CppMessageObj {
13579  public:
13580   enum FieldNumbers {
13581     kInputPacketsFieldNumber = 1,
13582     kInputBytesFieldNumber = 2,
13583     kOutputBytesFieldNumber = 3,
13584     kErrorsFieldNumber = 4,
13585   };
13586 
13587   TraceStats_FilterStats();
13588   ~TraceStats_FilterStats() override;
13589   TraceStats_FilterStats(TraceStats_FilterStats&&) noexcept;
13590   TraceStats_FilterStats& operator=(TraceStats_FilterStats&&);
13591   TraceStats_FilterStats(const TraceStats_FilterStats&);
13592   TraceStats_FilterStats& operator=(const TraceStats_FilterStats&);
13593   bool operator==(const TraceStats_FilterStats&) const;
operator !=(const TraceStats_FilterStats & other) const13594   bool operator!=(const TraceStats_FilterStats& other) const { return !(*this == other); }
13595 
13596   bool ParseFromArray(const void*, size_t) override;
13597   std::string SerializeAsString() const override;
13598   std::vector<uint8_t> SerializeAsArray() const override;
13599   void Serialize(::protozero::Message*) const;
13600 
has_input_packets() const13601   bool has_input_packets() const { return _has_field_[1]; }
input_packets() const13602   uint64_t input_packets() const { return input_packets_; }
set_input_packets(uint64_t value)13603   void set_input_packets(uint64_t value) { input_packets_ = value; _has_field_.set(1); }
13604 
has_input_bytes() const13605   bool has_input_bytes() const { return _has_field_[2]; }
input_bytes() const13606   uint64_t input_bytes() const { return input_bytes_; }
set_input_bytes(uint64_t value)13607   void set_input_bytes(uint64_t value) { input_bytes_ = value; _has_field_.set(2); }
13608 
has_output_bytes() const13609   bool has_output_bytes() const { return _has_field_[3]; }
output_bytes() const13610   uint64_t output_bytes() const { return output_bytes_; }
set_output_bytes(uint64_t value)13611   void set_output_bytes(uint64_t value) { output_bytes_ = value; _has_field_.set(3); }
13612 
has_errors() const13613   bool has_errors() const { return _has_field_[4]; }
errors() const13614   uint64_t errors() const { return errors_; }
set_errors(uint64_t value)13615   void set_errors(uint64_t value) { errors_ = value; _has_field_.set(4); }
13616 
13617  private:
13618   uint64_t input_packets_{};
13619   uint64_t input_bytes_{};
13620   uint64_t output_bytes_{};
13621   uint64_t errors_{};
13622 
13623   // Allows to preserve unknown protobuf fields for compatibility
13624   // with future versions of .proto files.
13625   std::string unknown_fields_;
13626 
13627   std::bitset<5> _has_field_{};
13628 };
13629 
13630 
13631 class PERFETTO_EXPORT TraceStats_BufferStats : public ::protozero::CppMessageObj {
13632  public:
13633   enum FieldNumbers {
13634     kBufferSizeFieldNumber = 12,
13635     kBytesWrittenFieldNumber = 1,
13636     kBytesOverwrittenFieldNumber = 13,
13637     kBytesReadFieldNumber = 14,
13638     kPaddingBytesWrittenFieldNumber = 15,
13639     kPaddingBytesClearedFieldNumber = 16,
13640     kChunksWrittenFieldNumber = 2,
13641     kChunksRewrittenFieldNumber = 10,
13642     kChunksOverwrittenFieldNumber = 3,
13643     kChunksDiscardedFieldNumber = 18,
13644     kChunksReadFieldNumber = 17,
13645     kChunksCommittedOutOfOrderFieldNumber = 11,
13646     kWriteWrapCountFieldNumber = 4,
13647     kPatchesSucceededFieldNumber = 5,
13648     kPatchesFailedFieldNumber = 6,
13649     kReadaheadsSucceededFieldNumber = 7,
13650     kReadaheadsFailedFieldNumber = 8,
13651     kAbiViolationsFieldNumber = 9,
13652     kTraceWriterPacketLossFieldNumber = 19,
13653   };
13654 
13655   TraceStats_BufferStats();
13656   ~TraceStats_BufferStats() override;
13657   TraceStats_BufferStats(TraceStats_BufferStats&&) noexcept;
13658   TraceStats_BufferStats& operator=(TraceStats_BufferStats&&);
13659   TraceStats_BufferStats(const TraceStats_BufferStats&);
13660   TraceStats_BufferStats& operator=(const TraceStats_BufferStats&);
13661   bool operator==(const TraceStats_BufferStats&) const;
operator !=(const TraceStats_BufferStats & other) const13662   bool operator!=(const TraceStats_BufferStats& other) const { return !(*this == other); }
13663 
13664   bool ParseFromArray(const void*, size_t) override;
13665   std::string SerializeAsString() const override;
13666   std::vector<uint8_t> SerializeAsArray() const override;
13667   void Serialize(::protozero::Message*) const;
13668 
has_buffer_size() const13669   bool has_buffer_size() const { return _has_field_[12]; }
buffer_size() const13670   uint64_t buffer_size() const { return buffer_size_; }
set_buffer_size(uint64_t value)13671   void set_buffer_size(uint64_t value) { buffer_size_ = value; _has_field_.set(12); }
13672 
has_bytes_written() const13673   bool has_bytes_written() const { return _has_field_[1]; }
bytes_written() const13674   uint64_t bytes_written() const { return bytes_written_; }
set_bytes_written(uint64_t value)13675   void set_bytes_written(uint64_t value) { bytes_written_ = value; _has_field_.set(1); }
13676 
has_bytes_overwritten() const13677   bool has_bytes_overwritten() const { return _has_field_[13]; }
bytes_overwritten() const13678   uint64_t bytes_overwritten() const { return bytes_overwritten_; }
set_bytes_overwritten(uint64_t value)13679   void set_bytes_overwritten(uint64_t value) { bytes_overwritten_ = value; _has_field_.set(13); }
13680 
has_bytes_read() const13681   bool has_bytes_read() const { return _has_field_[14]; }
bytes_read() const13682   uint64_t bytes_read() const { return bytes_read_; }
set_bytes_read(uint64_t value)13683   void set_bytes_read(uint64_t value) { bytes_read_ = value; _has_field_.set(14); }
13684 
has_padding_bytes_written() const13685   bool has_padding_bytes_written() const { return _has_field_[15]; }
padding_bytes_written() const13686   uint64_t padding_bytes_written() const { return padding_bytes_written_; }
set_padding_bytes_written(uint64_t value)13687   void set_padding_bytes_written(uint64_t value) { padding_bytes_written_ = value; _has_field_.set(15); }
13688 
has_padding_bytes_cleared() const13689   bool has_padding_bytes_cleared() const { return _has_field_[16]; }
padding_bytes_cleared() const13690   uint64_t padding_bytes_cleared() const { return padding_bytes_cleared_; }
set_padding_bytes_cleared(uint64_t value)13691   void set_padding_bytes_cleared(uint64_t value) { padding_bytes_cleared_ = value; _has_field_.set(16); }
13692 
has_chunks_written() const13693   bool has_chunks_written() const { return _has_field_[2]; }
chunks_written() const13694   uint64_t chunks_written() const { return chunks_written_; }
set_chunks_written(uint64_t value)13695   void set_chunks_written(uint64_t value) { chunks_written_ = value; _has_field_.set(2); }
13696 
has_chunks_rewritten() const13697   bool has_chunks_rewritten() const { return _has_field_[10]; }
chunks_rewritten() const13698   uint64_t chunks_rewritten() const { return chunks_rewritten_; }
set_chunks_rewritten(uint64_t value)13699   void set_chunks_rewritten(uint64_t value) { chunks_rewritten_ = value; _has_field_.set(10); }
13700 
has_chunks_overwritten() const13701   bool has_chunks_overwritten() const { return _has_field_[3]; }
chunks_overwritten() const13702   uint64_t chunks_overwritten() const { return chunks_overwritten_; }
set_chunks_overwritten(uint64_t value)13703   void set_chunks_overwritten(uint64_t value) { chunks_overwritten_ = value; _has_field_.set(3); }
13704 
has_chunks_discarded() const13705   bool has_chunks_discarded() const { return _has_field_[18]; }
chunks_discarded() const13706   uint64_t chunks_discarded() const { return chunks_discarded_; }
set_chunks_discarded(uint64_t value)13707   void set_chunks_discarded(uint64_t value) { chunks_discarded_ = value; _has_field_.set(18); }
13708 
has_chunks_read() const13709   bool has_chunks_read() const { return _has_field_[17]; }
chunks_read() const13710   uint64_t chunks_read() const { return chunks_read_; }
set_chunks_read(uint64_t value)13711   void set_chunks_read(uint64_t value) { chunks_read_ = value; _has_field_.set(17); }
13712 
has_chunks_committed_out_of_order() const13713   bool has_chunks_committed_out_of_order() const { return _has_field_[11]; }
chunks_committed_out_of_order() const13714   uint64_t chunks_committed_out_of_order() const { return chunks_committed_out_of_order_; }
set_chunks_committed_out_of_order(uint64_t value)13715   void set_chunks_committed_out_of_order(uint64_t value) { chunks_committed_out_of_order_ = value; _has_field_.set(11); }
13716 
has_write_wrap_count() const13717   bool has_write_wrap_count() const { return _has_field_[4]; }
write_wrap_count() const13718   uint64_t write_wrap_count() const { return write_wrap_count_; }
set_write_wrap_count(uint64_t value)13719   void set_write_wrap_count(uint64_t value) { write_wrap_count_ = value; _has_field_.set(4); }
13720 
has_patches_succeeded() const13721   bool has_patches_succeeded() const { return _has_field_[5]; }
patches_succeeded() const13722   uint64_t patches_succeeded() const { return patches_succeeded_; }
set_patches_succeeded(uint64_t value)13723   void set_patches_succeeded(uint64_t value) { patches_succeeded_ = value; _has_field_.set(5); }
13724 
has_patches_failed() const13725   bool has_patches_failed() const { return _has_field_[6]; }
patches_failed() const13726   uint64_t patches_failed() const { return patches_failed_; }
set_patches_failed(uint64_t value)13727   void set_patches_failed(uint64_t value) { patches_failed_ = value; _has_field_.set(6); }
13728 
has_readaheads_succeeded() const13729   bool has_readaheads_succeeded() const { return _has_field_[7]; }
readaheads_succeeded() const13730   uint64_t readaheads_succeeded() const { return readaheads_succeeded_; }
set_readaheads_succeeded(uint64_t value)13731   void set_readaheads_succeeded(uint64_t value) { readaheads_succeeded_ = value; _has_field_.set(7); }
13732 
has_readaheads_failed() const13733   bool has_readaheads_failed() const { return _has_field_[8]; }
readaheads_failed() const13734   uint64_t readaheads_failed() const { return readaheads_failed_; }
set_readaheads_failed(uint64_t value)13735   void set_readaheads_failed(uint64_t value) { readaheads_failed_ = value; _has_field_.set(8); }
13736 
has_abi_violations() const13737   bool has_abi_violations() const { return _has_field_[9]; }
abi_violations() const13738   uint64_t abi_violations() const { return abi_violations_; }
set_abi_violations(uint64_t value)13739   void set_abi_violations(uint64_t value) { abi_violations_ = value; _has_field_.set(9); }
13740 
has_trace_writer_packet_loss() const13741   bool has_trace_writer_packet_loss() const { return _has_field_[19]; }
trace_writer_packet_loss() const13742   uint64_t trace_writer_packet_loss() const { return trace_writer_packet_loss_; }
set_trace_writer_packet_loss(uint64_t value)13743   void set_trace_writer_packet_loss(uint64_t value) { trace_writer_packet_loss_ = value; _has_field_.set(19); }
13744 
13745  private:
13746   uint64_t buffer_size_{};
13747   uint64_t bytes_written_{};
13748   uint64_t bytes_overwritten_{};
13749   uint64_t bytes_read_{};
13750   uint64_t padding_bytes_written_{};
13751   uint64_t padding_bytes_cleared_{};
13752   uint64_t chunks_written_{};
13753   uint64_t chunks_rewritten_{};
13754   uint64_t chunks_overwritten_{};
13755   uint64_t chunks_discarded_{};
13756   uint64_t chunks_read_{};
13757   uint64_t chunks_committed_out_of_order_{};
13758   uint64_t write_wrap_count_{};
13759   uint64_t patches_succeeded_{};
13760   uint64_t patches_failed_{};
13761   uint64_t readaheads_succeeded_{};
13762   uint64_t readaheads_failed_{};
13763   uint64_t abi_violations_{};
13764   uint64_t trace_writer_packet_loss_{};
13765 
13766   // Allows to preserve unknown protobuf fields for compatibility
13767   // with future versions of .proto files.
13768   std::string unknown_fields_;
13769 
13770   std::bitset<20> _has_field_{};
13771 };
13772 
13773 }  // namespace perfetto
13774 }  // namespace protos
13775 }  // namespace gen
13776 
13777 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACE_STATS_PROTO_CPP_H_
13778 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
13779 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
13780 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
13781 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
13782 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
13783 #if defined(__GNUC__) || defined(__clang__)
13784 #pragma GCC diagnostic push
13785 #pragma GCC diagnostic ignored "-Wfloat-equal"
13786 #endif
13787 // gen_amalgamated expanded: #include "protos/perfetto/common/trace_stats.gen.h"
13788 
13789 namespace perfetto {
13790 namespace protos {
13791 namespace gen {
13792 
13793 TraceStats::TraceStats() = default;
13794 TraceStats::~TraceStats() = default;
13795 TraceStats::TraceStats(const TraceStats&) = default;
13796 TraceStats& TraceStats::operator=(const TraceStats&) = default;
13797 TraceStats::TraceStats(TraceStats&&) noexcept = default;
13798 TraceStats& TraceStats::operator=(TraceStats&&) = default;
13799 
operator ==(const TraceStats & other) const13800 bool TraceStats::operator==(const TraceStats& other) const {
13801   return unknown_fields_ == other.unknown_fields_
13802    && buffer_stats_ == other.buffer_stats_
13803    && producers_connected_ == other.producers_connected_
13804    && producers_seen_ == other.producers_seen_
13805    && data_sources_registered_ == other.data_sources_registered_
13806    && data_sources_seen_ == other.data_sources_seen_
13807    && tracing_sessions_ == other.tracing_sessions_
13808    && total_buffers_ == other.total_buffers_
13809    && chunks_discarded_ == other.chunks_discarded_
13810    && patches_discarded_ == other.patches_discarded_
13811    && invalid_packets_ == other.invalid_packets_
13812    && filter_stats_ == other.filter_stats_;
13813 }
13814 
buffer_stats_size() const13815 int TraceStats::buffer_stats_size() const { return static_cast<int>(buffer_stats_.size()); }
clear_buffer_stats()13816 void TraceStats::clear_buffer_stats() { buffer_stats_.clear(); }
add_buffer_stats()13817 TraceStats_BufferStats* TraceStats::add_buffer_stats() { buffer_stats_.emplace_back(); return &buffer_stats_.back(); }
ParseFromArray(const void * raw,size_t size)13818 bool TraceStats::ParseFromArray(const void* raw, size_t size) {
13819   buffer_stats_.clear();
13820   unknown_fields_.clear();
13821   bool packed_error = false;
13822 
13823   ::protozero::ProtoDecoder dec(raw, size);
13824   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
13825     if (field.id() < _has_field_.size()) {
13826       _has_field_.set(field.id());
13827     }
13828     switch (field.id()) {
13829       case 1 /* buffer_stats */:
13830         buffer_stats_.emplace_back();
13831         buffer_stats_.back().ParseFromArray(field.data(), field.size());
13832         break;
13833       case 2 /* producers_connected */:
13834         field.get(&producers_connected_);
13835         break;
13836       case 3 /* producers_seen */:
13837         field.get(&producers_seen_);
13838         break;
13839       case 4 /* data_sources_registered */:
13840         field.get(&data_sources_registered_);
13841         break;
13842       case 5 /* data_sources_seen */:
13843         field.get(&data_sources_seen_);
13844         break;
13845       case 6 /* tracing_sessions */:
13846         field.get(&tracing_sessions_);
13847         break;
13848       case 7 /* total_buffers */:
13849         field.get(&total_buffers_);
13850         break;
13851       case 8 /* chunks_discarded */:
13852         field.get(&chunks_discarded_);
13853         break;
13854       case 9 /* patches_discarded */:
13855         field.get(&patches_discarded_);
13856         break;
13857       case 10 /* invalid_packets */:
13858         field.get(&invalid_packets_);
13859         break;
13860       case 11 /* filter_stats */:
13861         (*filter_stats_).ParseFromArray(field.data(), field.size());
13862         break;
13863       default:
13864         field.SerializeAndAppendTo(&unknown_fields_);
13865         break;
13866     }
13867   }
13868   return !packed_error && !dec.bytes_left();
13869 }
13870 
SerializeAsString() const13871 std::string TraceStats::SerializeAsString() const {
13872   ::protozero::HeapBuffered<::protozero::Message> msg;
13873   Serialize(msg.get());
13874   return msg.SerializeAsString();
13875 }
13876 
SerializeAsArray() const13877 std::vector<uint8_t> TraceStats::SerializeAsArray() const {
13878   ::protozero::HeapBuffered<::protozero::Message> msg;
13879   Serialize(msg.get());
13880   return msg.SerializeAsArray();
13881 }
13882 
Serialize(::protozero::Message * msg) const13883 void TraceStats::Serialize(::protozero::Message* msg) const {
13884   // Field 1: buffer_stats
13885   for (auto& it : buffer_stats_) {
13886     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
13887   }
13888 
13889   // Field 2: producers_connected
13890   if (_has_field_[2]) {
13891     msg->AppendVarInt(2, producers_connected_);
13892   }
13893 
13894   // Field 3: producers_seen
13895   if (_has_field_[3]) {
13896     msg->AppendVarInt(3, producers_seen_);
13897   }
13898 
13899   // Field 4: data_sources_registered
13900   if (_has_field_[4]) {
13901     msg->AppendVarInt(4, data_sources_registered_);
13902   }
13903 
13904   // Field 5: data_sources_seen
13905   if (_has_field_[5]) {
13906     msg->AppendVarInt(5, data_sources_seen_);
13907   }
13908 
13909   // Field 6: tracing_sessions
13910   if (_has_field_[6]) {
13911     msg->AppendVarInt(6, tracing_sessions_);
13912   }
13913 
13914   // Field 7: total_buffers
13915   if (_has_field_[7]) {
13916     msg->AppendVarInt(7, total_buffers_);
13917   }
13918 
13919   // Field 8: chunks_discarded
13920   if (_has_field_[8]) {
13921     msg->AppendVarInt(8, chunks_discarded_);
13922   }
13923 
13924   // Field 9: patches_discarded
13925   if (_has_field_[9]) {
13926     msg->AppendVarInt(9, patches_discarded_);
13927   }
13928 
13929   // Field 10: invalid_packets
13930   if (_has_field_[10]) {
13931     msg->AppendVarInt(10, invalid_packets_);
13932   }
13933 
13934   // Field 11: filter_stats
13935   if (_has_field_[11]) {
13936     (*filter_stats_).Serialize(msg->BeginNestedMessage<::protozero::Message>(11));
13937   }
13938 
13939   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
13940 }
13941 
13942 
13943 TraceStats_FilterStats::TraceStats_FilterStats() = default;
13944 TraceStats_FilterStats::~TraceStats_FilterStats() = default;
13945 TraceStats_FilterStats::TraceStats_FilterStats(const TraceStats_FilterStats&) = default;
13946 TraceStats_FilterStats& TraceStats_FilterStats::operator=(const TraceStats_FilterStats&) = default;
13947 TraceStats_FilterStats::TraceStats_FilterStats(TraceStats_FilterStats&&) noexcept = default;
13948 TraceStats_FilterStats& TraceStats_FilterStats::operator=(TraceStats_FilterStats&&) = default;
13949 
operator ==(const TraceStats_FilterStats & other) const13950 bool TraceStats_FilterStats::operator==(const TraceStats_FilterStats& other) const {
13951   return unknown_fields_ == other.unknown_fields_
13952    && input_packets_ == other.input_packets_
13953    && input_bytes_ == other.input_bytes_
13954    && output_bytes_ == other.output_bytes_
13955    && errors_ == other.errors_;
13956 }
13957 
ParseFromArray(const void * raw,size_t size)13958 bool TraceStats_FilterStats::ParseFromArray(const void* raw, size_t size) {
13959   unknown_fields_.clear();
13960   bool packed_error = false;
13961 
13962   ::protozero::ProtoDecoder dec(raw, size);
13963   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
13964     if (field.id() < _has_field_.size()) {
13965       _has_field_.set(field.id());
13966     }
13967     switch (field.id()) {
13968       case 1 /* input_packets */:
13969         field.get(&input_packets_);
13970         break;
13971       case 2 /* input_bytes */:
13972         field.get(&input_bytes_);
13973         break;
13974       case 3 /* output_bytes */:
13975         field.get(&output_bytes_);
13976         break;
13977       case 4 /* errors */:
13978         field.get(&errors_);
13979         break;
13980       default:
13981         field.SerializeAndAppendTo(&unknown_fields_);
13982         break;
13983     }
13984   }
13985   return !packed_error && !dec.bytes_left();
13986 }
13987 
SerializeAsString() const13988 std::string TraceStats_FilterStats::SerializeAsString() const {
13989   ::protozero::HeapBuffered<::protozero::Message> msg;
13990   Serialize(msg.get());
13991   return msg.SerializeAsString();
13992 }
13993 
SerializeAsArray() const13994 std::vector<uint8_t> TraceStats_FilterStats::SerializeAsArray() const {
13995   ::protozero::HeapBuffered<::protozero::Message> msg;
13996   Serialize(msg.get());
13997   return msg.SerializeAsArray();
13998 }
13999 
Serialize(::protozero::Message * msg) const14000 void TraceStats_FilterStats::Serialize(::protozero::Message* msg) const {
14001   // Field 1: input_packets
14002   if (_has_field_[1]) {
14003     msg->AppendVarInt(1, input_packets_);
14004   }
14005 
14006   // Field 2: input_bytes
14007   if (_has_field_[2]) {
14008     msg->AppendVarInt(2, input_bytes_);
14009   }
14010 
14011   // Field 3: output_bytes
14012   if (_has_field_[3]) {
14013     msg->AppendVarInt(3, output_bytes_);
14014   }
14015 
14016   // Field 4: errors
14017   if (_has_field_[4]) {
14018     msg->AppendVarInt(4, errors_);
14019   }
14020 
14021   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
14022 }
14023 
14024 
14025 TraceStats_BufferStats::TraceStats_BufferStats() = default;
14026 TraceStats_BufferStats::~TraceStats_BufferStats() = default;
14027 TraceStats_BufferStats::TraceStats_BufferStats(const TraceStats_BufferStats&) = default;
14028 TraceStats_BufferStats& TraceStats_BufferStats::operator=(const TraceStats_BufferStats&) = default;
14029 TraceStats_BufferStats::TraceStats_BufferStats(TraceStats_BufferStats&&) noexcept = default;
14030 TraceStats_BufferStats& TraceStats_BufferStats::operator=(TraceStats_BufferStats&&) = default;
14031 
operator ==(const TraceStats_BufferStats & other) const14032 bool TraceStats_BufferStats::operator==(const TraceStats_BufferStats& other) const {
14033   return unknown_fields_ == other.unknown_fields_
14034    && buffer_size_ == other.buffer_size_
14035    && bytes_written_ == other.bytes_written_
14036    && bytes_overwritten_ == other.bytes_overwritten_
14037    && bytes_read_ == other.bytes_read_
14038    && padding_bytes_written_ == other.padding_bytes_written_
14039    && padding_bytes_cleared_ == other.padding_bytes_cleared_
14040    && chunks_written_ == other.chunks_written_
14041    && chunks_rewritten_ == other.chunks_rewritten_
14042    && chunks_overwritten_ == other.chunks_overwritten_
14043    && chunks_discarded_ == other.chunks_discarded_
14044    && chunks_read_ == other.chunks_read_
14045    && chunks_committed_out_of_order_ == other.chunks_committed_out_of_order_
14046    && write_wrap_count_ == other.write_wrap_count_
14047    && patches_succeeded_ == other.patches_succeeded_
14048    && patches_failed_ == other.patches_failed_
14049    && readaheads_succeeded_ == other.readaheads_succeeded_
14050    && readaheads_failed_ == other.readaheads_failed_
14051    && abi_violations_ == other.abi_violations_
14052    && trace_writer_packet_loss_ == other.trace_writer_packet_loss_;
14053 }
14054 
ParseFromArray(const void * raw,size_t size)14055 bool TraceStats_BufferStats::ParseFromArray(const void* raw, size_t size) {
14056   unknown_fields_.clear();
14057   bool packed_error = false;
14058 
14059   ::protozero::ProtoDecoder dec(raw, size);
14060   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
14061     if (field.id() < _has_field_.size()) {
14062       _has_field_.set(field.id());
14063     }
14064     switch (field.id()) {
14065       case 12 /* buffer_size */:
14066         field.get(&buffer_size_);
14067         break;
14068       case 1 /* bytes_written */:
14069         field.get(&bytes_written_);
14070         break;
14071       case 13 /* bytes_overwritten */:
14072         field.get(&bytes_overwritten_);
14073         break;
14074       case 14 /* bytes_read */:
14075         field.get(&bytes_read_);
14076         break;
14077       case 15 /* padding_bytes_written */:
14078         field.get(&padding_bytes_written_);
14079         break;
14080       case 16 /* padding_bytes_cleared */:
14081         field.get(&padding_bytes_cleared_);
14082         break;
14083       case 2 /* chunks_written */:
14084         field.get(&chunks_written_);
14085         break;
14086       case 10 /* chunks_rewritten */:
14087         field.get(&chunks_rewritten_);
14088         break;
14089       case 3 /* chunks_overwritten */:
14090         field.get(&chunks_overwritten_);
14091         break;
14092       case 18 /* chunks_discarded */:
14093         field.get(&chunks_discarded_);
14094         break;
14095       case 17 /* chunks_read */:
14096         field.get(&chunks_read_);
14097         break;
14098       case 11 /* chunks_committed_out_of_order */:
14099         field.get(&chunks_committed_out_of_order_);
14100         break;
14101       case 4 /* write_wrap_count */:
14102         field.get(&write_wrap_count_);
14103         break;
14104       case 5 /* patches_succeeded */:
14105         field.get(&patches_succeeded_);
14106         break;
14107       case 6 /* patches_failed */:
14108         field.get(&patches_failed_);
14109         break;
14110       case 7 /* readaheads_succeeded */:
14111         field.get(&readaheads_succeeded_);
14112         break;
14113       case 8 /* readaheads_failed */:
14114         field.get(&readaheads_failed_);
14115         break;
14116       case 9 /* abi_violations */:
14117         field.get(&abi_violations_);
14118         break;
14119       case 19 /* trace_writer_packet_loss */:
14120         field.get(&trace_writer_packet_loss_);
14121         break;
14122       default:
14123         field.SerializeAndAppendTo(&unknown_fields_);
14124         break;
14125     }
14126   }
14127   return !packed_error && !dec.bytes_left();
14128 }
14129 
SerializeAsString() const14130 std::string TraceStats_BufferStats::SerializeAsString() const {
14131   ::protozero::HeapBuffered<::protozero::Message> msg;
14132   Serialize(msg.get());
14133   return msg.SerializeAsString();
14134 }
14135 
SerializeAsArray() const14136 std::vector<uint8_t> TraceStats_BufferStats::SerializeAsArray() const {
14137   ::protozero::HeapBuffered<::protozero::Message> msg;
14138   Serialize(msg.get());
14139   return msg.SerializeAsArray();
14140 }
14141 
Serialize(::protozero::Message * msg) const14142 void TraceStats_BufferStats::Serialize(::protozero::Message* msg) const {
14143   // Field 12: buffer_size
14144   if (_has_field_[12]) {
14145     msg->AppendVarInt(12, buffer_size_);
14146   }
14147 
14148   // Field 1: bytes_written
14149   if (_has_field_[1]) {
14150     msg->AppendVarInt(1, bytes_written_);
14151   }
14152 
14153   // Field 13: bytes_overwritten
14154   if (_has_field_[13]) {
14155     msg->AppendVarInt(13, bytes_overwritten_);
14156   }
14157 
14158   // Field 14: bytes_read
14159   if (_has_field_[14]) {
14160     msg->AppendVarInt(14, bytes_read_);
14161   }
14162 
14163   // Field 15: padding_bytes_written
14164   if (_has_field_[15]) {
14165     msg->AppendVarInt(15, padding_bytes_written_);
14166   }
14167 
14168   // Field 16: padding_bytes_cleared
14169   if (_has_field_[16]) {
14170     msg->AppendVarInt(16, padding_bytes_cleared_);
14171   }
14172 
14173   // Field 2: chunks_written
14174   if (_has_field_[2]) {
14175     msg->AppendVarInt(2, chunks_written_);
14176   }
14177 
14178   // Field 10: chunks_rewritten
14179   if (_has_field_[10]) {
14180     msg->AppendVarInt(10, chunks_rewritten_);
14181   }
14182 
14183   // Field 3: chunks_overwritten
14184   if (_has_field_[3]) {
14185     msg->AppendVarInt(3, chunks_overwritten_);
14186   }
14187 
14188   // Field 18: chunks_discarded
14189   if (_has_field_[18]) {
14190     msg->AppendVarInt(18, chunks_discarded_);
14191   }
14192 
14193   // Field 17: chunks_read
14194   if (_has_field_[17]) {
14195     msg->AppendVarInt(17, chunks_read_);
14196   }
14197 
14198   // Field 11: chunks_committed_out_of_order
14199   if (_has_field_[11]) {
14200     msg->AppendVarInt(11, chunks_committed_out_of_order_);
14201   }
14202 
14203   // Field 4: write_wrap_count
14204   if (_has_field_[4]) {
14205     msg->AppendVarInt(4, write_wrap_count_);
14206   }
14207 
14208   // Field 5: patches_succeeded
14209   if (_has_field_[5]) {
14210     msg->AppendVarInt(5, patches_succeeded_);
14211   }
14212 
14213   // Field 6: patches_failed
14214   if (_has_field_[6]) {
14215     msg->AppendVarInt(6, patches_failed_);
14216   }
14217 
14218   // Field 7: readaheads_succeeded
14219   if (_has_field_[7]) {
14220     msg->AppendVarInt(7, readaheads_succeeded_);
14221   }
14222 
14223   // Field 8: readaheads_failed
14224   if (_has_field_[8]) {
14225     msg->AppendVarInt(8, readaheads_failed_);
14226   }
14227 
14228   // Field 9: abi_violations
14229   if (_has_field_[9]) {
14230     msg->AppendVarInt(9, abi_violations_);
14231   }
14232 
14233   // Field 19: trace_writer_packet_loss
14234   if (_has_field_[19]) {
14235     msg->AppendVarInt(19, trace_writer_packet_loss_);
14236   }
14237 
14238   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
14239 }
14240 
14241 }  // namespace perfetto
14242 }  // namespace protos
14243 }  // namespace gen
14244 #if defined(__GNUC__) || defined(__clang__)
14245 #pragma GCC diagnostic pop
14246 #endif
14247 // gen_amalgamated begin source: gen/protos/perfetto/common/tracing_service_capabilities.gen.cc
14248 // gen_amalgamated begin header: gen/protos/perfetto/common/tracing_service_capabilities.gen.h
14249 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
14250 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_CAPABILITIES_PROTO_CPP_H_
14251 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_CAPABILITIES_PROTO_CPP_H_
14252 
14253 #include <stdint.h>
14254 #include <bitset>
14255 #include <vector>
14256 #include <string>
14257 #include <type_traits>
14258 
14259 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
14260 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
14261 // gen_amalgamated expanded: #include "perfetto/base/export.h"
14262 
14263 namespace perfetto {
14264 namespace protos {
14265 namespace gen {
14266 class TracingServiceCapabilities;
14267 enum ObservableEvents_Type : int;
14268 }  // namespace perfetto
14269 }  // namespace protos
14270 }  // namespace gen
14271 
14272 namespace protozero {
14273 class Message;
14274 }  // namespace protozero
14275 
14276 namespace perfetto {
14277 namespace protos {
14278 namespace gen {
14279 
14280 class PERFETTO_EXPORT TracingServiceCapabilities : public ::protozero::CppMessageObj {
14281  public:
14282   enum FieldNumbers {
14283     kHasQueryCapabilitiesFieldNumber = 1,
14284     kObservableEventsFieldNumber = 2,
14285     kHasTraceConfigOutputPathFieldNumber = 3,
14286   };
14287 
14288   TracingServiceCapabilities();
14289   ~TracingServiceCapabilities() override;
14290   TracingServiceCapabilities(TracingServiceCapabilities&&) noexcept;
14291   TracingServiceCapabilities& operator=(TracingServiceCapabilities&&);
14292   TracingServiceCapabilities(const TracingServiceCapabilities&);
14293   TracingServiceCapabilities& operator=(const TracingServiceCapabilities&);
14294   bool operator==(const TracingServiceCapabilities&) const;
operator !=(const TracingServiceCapabilities & other) const14295   bool operator!=(const TracingServiceCapabilities& other) const { return !(*this == other); }
14296 
14297   bool ParseFromArray(const void*, size_t) override;
14298   std::string SerializeAsString() const override;
14299   std::vector<uint8_t> SerializeAsArray() const override;
14300   void Serialize(::protozero::Message*) const;
14301 
has_has_query_capabilities() const14302   bool has_has_query_capabilities() const { return _has_field_[1]; }
has_query_capabilities() const14303   bool has_query_capabilities() const { return has_query_capabilities_; }
set_has_query_capabilities(bool value)14304   void set_has_query_capabilities(bool value) { has_query_capabilities_ = value; _has_field_.set(1); }
14305 
observable_events() const14306   const std::vector<ObservableEvents_Type>& observable_events() const { return observable_events_; }
mutable_observable_events()14307   std::vector<ObservableEvents_Type>* mutable_observable_events() { return &observable_events_; }
observable_events_size() const14308   int observable_events_size() const { return static_cast<int>(observable_events_.size()); }
clear_observable_events()14309   void clear_observable_events() { observable_events_.clear(); }
add_observable_events(ObservableEvents_Type value)14310   void add_observable_events(ObservableEvents_Type value) { observable_events_.emplace_back(value); }
add_observable_events()14311   ObservableEvents_Type* add_observable_events() { observable_events_.emplace_back(); return &observable_events_.back(); }
14312 
has_has_trace_config_output_path() const14313   bool has_has_trace_config_output_path() const { return _has_field_[3]; }
has_trace_config_output_path() const14314   bool has_trace_config_output_path() const { return has_trace_config_output_path_; }
set_has_trace_config_output_path(bool value)14315   void set_has_trace_config_output_path(bool value) { has_trace_config_output_path_ = value; _has_field_.set(3); }
14316 
14317  private:
14318   bool has_query_capabilities_{};
14319   std::vector<ObservableEvents_Type> observable_events_;
14320   bool has_trace_config_output_path_{};
14321 
14322   // Allows to preserve unknown protobuf fields for compatibility
14323   // with future versions of .proto files.
14324   std::string unknown_fields_;
14325 
14326   std::bitset<4> _has_field_{};
14327 };
14328 
14329 }  // namespace perfetto
14330 }  // namespace protos
14331 }  // namespace gen
14332 
14333 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_CAPABILITIES_PROTO_CPP_H_
14334 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
14335 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
14336 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
14337 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
14338 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
14339 #if defined(__GNUC__) || defined(__clang__)
14340 #pragma GCC diagnostic push
14341 #pragma GCC diagnostic ignored "-Wfloat-equal"
14342 #endif
14343 // gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_capabilities.gen.h"
14344 // gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"
14345 
14346 namespace perfetto {
14347 namespace protos {
14348 namespace gen {
14349 
14350 TracingServiceCapabilities::TracingServiceCapabilities() = default;
14351 TracingServiceCapabilities::~TracingServiceCapabilities() = default;
14352 TracingServiceCapabilities::TracingServiceCapabilities(const TracingServiceCapabilities&) = default;
14353 TracingServiceCapabilities& TracingServiceCapabilities::operator=(const TracingServiceCapabilities&) = default;
14354 TracingServiceCapabilities::TracingServiceCapabilities(TracingServiceCapabilities&&) noexcept = default;
14355 TracingServiceCapabilities& TracingServiceCapabilities::operator=(TracingServiceCapabilities&&) = default;
14356 
operator ==(const TracingServiceCapabilities & other) const14357 bool TracingServiceCapabilities::operator==(const TracingServiceCapabilities& other) const {
14358   return unknown_fields_ == other.unknown_fields_
14359    && has_query_capabilities_ == other.has_query_capabilities_
14360    && observable_events_ == other.observable_events_
14361    && has_trace_config_output_path_ == other.has_trace_config_output_path_;
14362 }
14363 
ParseFromArray(const void * raw,size_t size)14364 bool TracingServiceCapabilities::ParseFromArray(const void* raw, size_t size) {
14365   observable_events_.clear();
14366   unknown_fields_.clear();
14367   bool packed_error = false;
14368 
14369   ::protozero::ProtoDecoder dec(raw, size);
14370   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
14371     if (field.id() < _has_field_.size()) {
14372       _has_field_.set(field.id());
14373     }
14374     switch (field.id()) {
14375       case 1 /* has_query_capabilities */:
14376         field.get(&has_query_capabilities_);
14377         break;
14378       case 2 /* observable_events */:
14379         observable_events_.emplace_back();
14380         field.get(&observable_events_.back());
14381         break;
14382       case 3 /* has_trace_config_output_path */:
14383         field.get(&has_trace_config_output_path_);
14384         break;
14385       default:
14386         field.SerializeAndAppendTo(&unknown_fields_);
14387         break;
14388     }
14389   }
14390   return !packed_error && !dec.bytes_left();
14391 }
14392 
SerializeAsString() const14393 std::string TracingServiceCapabilities::SerializeAsString() const {
14394   ::protozero::HeapBuffered<::protozero::Message> msg;
14395   Serialize(msg.get());
14396   return msg.SerializeAsString();
14397 }
14398 
SerializeAsArray() const14399 std::vector<uint8_t> TracingServiceCapabilities::SerializeAsArray() const {
14400   ::protozero::HeapBuffered<::protozero::Message> msg;
14401   Serialize(msg.get());
14402   return msg.SerializeAsArray();
14403 }
14404 
Serialize(::protozero::Message * msg) const14405 void TracingServiceCapabilities::Serialize(::protozero::Message* msg) const {
14406   // Field 1: has_query_capabilities
14407   if (_has_field_[1]) {
14408     msg->AppendTinyVarInt(1, has_query_capabilities_);
14409   }
14410 
14411   // Field 2: observable_events
14412   for (auto& it : observable_events_) {
14413     msg->AppendVarInt(2, it);
14414   }
14415 
14416   // Field 3: has_trace_config_output_path
14417   if (_has_field_[3]) {
14418     msg->AppendTinyVarInt(3, has_trace_config_output_path_);
14419   }
14420 
14421   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
14422 }
14423 
14424 }  // namespace perfetto
14425 }  // namespace protos
14426 }  // namespace gen
14427 #if defined(__GNUC__) || defined(__clang__)
14428 #pragma GCC diagnostic pop
14429 #endif
14430 // gen_amalgamated begin source: gen/protos/perfetto/common/tracing_service_state.gen.cc
14431 // gen_amalgamated begin header: gen/protos/perfetto/common/tracing_service_state.gen.h
14432 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
14433 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_STATE_PROTO_CPP_H_
14434 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_STATE_PROTO_CPP_H_
14435 
14436 #include <stdint.h>
14437 #include <bitset>
14438 #include <vector>
14439 #include <string>
14440 #include <type_traits>
14441 
14442 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
14443 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
14444 // gen_amalgamated expanded: #include "perfetto/base/export.h"
14445 
14446 namespace perfetto {
14447 namespace protos {
14448 namespace gen {
14449 class TracingServiceState;
14450 class TracingServiceState_DataSource;
14451 class DataSourceDescriptor;
14452 class TracingServiceState_Producer;
14453 }  // namespace perfetto
14454 }  // namespace protos
14455 }  // namespace gen
14456 
14457 namespace protozero {
14458 class Message;
14459 }  // namespace protozero
14460 
14461 namespace perfetto {
14462 namespace protos {
14463 namespace gen {
14464 
14465 class PERFETTO_EXPORT TracingServiceState : public ::protozero::CppMessageObj {
14466  public:
14467   using Producer = TracingServiceState_Producer;
14468   using DataSource = TracingServiceState_DataSource;
14469   enum FieldNumbers {
14470     kProducersFieldNumber = 1,
14471     kDataSourcesFieldNumber = 2,
14472     kNumSessionsFieldNumber = 3,
14473     kNumSessionsStartedFieldNumber = 4,
14474     kTracingServiceVersionFieldNumber = 5,
14475   };
14476 
14477   TracingServiceState();
14478   ~TracingServiceState() override;
14479   TracingServiceState(TracingServiceState&&) noexcept;
14480   TracingServiceState& operator=(TracingServiceState&&);
14481   TracingServiceState(const TracingServiceState&);
14482   TracingServiceState& operator=(const TracingServiceState&);
14483   bool operator==(const TracingServiceState&) const;
operator !=(const TracingServiceState & other) const14484   bool operator!=(const TracingServiceState& other) const { return !(*this == other); }
14485 
14486   bool ParseFromArray(const void*, size_t) override;
14487   std::string SerializeAsString() const override;
14488   std::vector<uint8_t> SerializeAsArray() const override;
14489   void Serialize(::protozero::Message*) const;
14490 
producers() const14491   const std::vector<TracingServiceState_Producer>& producers() const { return producers_; }
mutable_producers()14492   std::vector<TracingServiceState_Producer>* mutable_producers() { return &producers_; }
14493   int producers_size() const;
14494   void clear_producers();
14495   TracingServiceState_Producer* add_producers();
14496 
data_sources() const14497   const std::vector<TracingServiceState_DataSource>& data_sources() const { return data_sources_; }
mutable_data_sources()14498   std::vector<TracingServiceState_DataSource>* mutable_data_sources() { return &data_sources_; }
14499   int data_sources_size() const;
14500   void clear_data_sources();
14501   TracingServiceState_DataSource* add_data_sources();
14502 
has_num_sessions() const14503   bool has_num_sessions() const { return _has_field_[3]; }
num_sessions() const14504   int32_t num_sessions() const { return num_sessions_; }
set_num_sessions(int32_t value)14505   void set_num_sessions(int32_t value) { num_sessions_ = value; _has_field_.set(3); }
14506 
has_num_sessions_started() const14507   bool has_num_sessions_started() const { return _has_field_[4]; }
num_sessions_started() const14508   int32_t num_sessions_started() const { return num_sessions_started_; }
set_num_sessions_started(int32_t value)14509   void set_num_sessions_started(int32_t value) { num_sessions_started_ = value; _has_field_.set(4); }
14510 
has_tracing_service_version() const14511   bool has_tracing_service_version() const { return _has_field_[5]; }
tracing_service_version() const14512   const std::string& tracing_service_version() const { return tracing_service_version_; }
set_tracing_service_version(const std::string & value)14513   void set_tracing_service_version(const std::string& value) { tracing_service_version_ = value; _has_field_.set(5); }
14514 
14515  private:
14516   std::vector<TracingServiceState_Producer> producers_;
14517   std::vector<TracingServiceState_DataSource> data_sources_;
14518   int32_t num_sessions_{};
14519   int32_t num_sessions_started_{};
14520   std::string tracing_service_version_{};
14521 
14522   // Allows to preserve unknown protobuf fields for compatibility
14523   // with future versions of .proto files.
14524   std::string unknown_fields_;
14525 
14526   std::bitset<6> _has_field_{};
14527 };
14528 
14529 
14530 class PERFETTO_EXPORT TracingServiceState_DataSource : public ::protozero::CppMessageObj {
14531  public:
14532   enum FieldNumbers {
14533     kDsDescriptorFieldNumber = 1,
14534     kProducerIdFieldNumber = 2,
14535   };
14536 
14537   TracingServiceState_DataSource();
14538   ~TracingServiceState_DataSource() override;
14539   TracingServiceState_DataSource(TracingServiceState_DataSource&&) noexcept;
14540   TracingServiceState_DataSource& operator=(TracingServiceState_DataSource&&);
14541   TracingServiceState_DataSource(const TracingServiceState_DataSource&);
14542   TracingServiceState_DataSource& operator=(const TracingServiceState_DataSource&);
14543   bool operator==(const TracingServiceState_DataSource&) const;
operator !=(const TracingServiceState_DataSource & other) const14544   bool operator!=(const TracingServiceState_DataSource& other) const { return !(*this == other); }
14545 
14546   bool ParseFromArray(const void*, size_t) override;
14547   std::string SerializeAsString() const override;
14548   std::vector<uint8_t> SerializeAsArray() const override;
14549   void Serialize(::protozero::Message*) const;
14550 
has_ds_descriptor() const14551   bool has_ds_descriptor() const { return _has_field_[1]; }
ds_descriptor() const14552   const DataSourceDescriptor& ds_descriptor() const { return *ds_descriptor_; }
mutable_ds_descriptor()14553   DataSourceDescriptor* mutable_ds_descriptor() { _has_field_.set(1); return ds_descriptor_.get(); }
14554 
has_producer_id() const14555   bool has_producer_id() const { return _has_field_[2]; }
producer_id() const14556   int32_t producer_id() const { return producer_id_; }
set_producer_id(int32_t value)14557   void set_producer_id(int32_t value) { producer_id_ = value; _has_field_.set(2); }
14558 
14559  private:
14560   ::protozero::CopyablePtr<DataSourceDescriptor> ds_descriptor_;
14561   int32_t producer_id_{};
14562 
14563   // Allows to preserve unknown protobuf fields for compatibility
14564   // with future versions of .proto files.
14565   std::string unknown_fields_;
14566 
14567   std::bitset<3> _has_field_{};
14568 };
14569 
14570 
14571 class PERFETTO_EXPORT TracingServiceState_Producer : public ::protozero::CppMessageObj {
14572  public:
14573   enum FieldNumbers {
14574     kIdFieldNumber = 1,
14575     kNameFieldNumber = 2,
14576     kUidFieldNumber = 3,
14577     kSdkVersionFieldNumber = 4,
14578   };
14579 
14580   TracingServiceState_Producer();
14581   ~TracingServiceState_Producer() override;
14582   TracingServiceState_Producer(TracingServiceState_Producer&&) noexcept;
14583   TracingServiceState_Producer& operator=(TracingServiceState_Producer&&);
14584   TracingServiceState_Producer(const TracingServiceState_Producer&);
14585   TracingServiceState_Producer& operator=(const TracingServiceState_Producer&);
14586   bool operator==(const TracingServiceState_Producer&) const;
operator !=(const TracingServiceState_Producer & other) const14587   bool operator!=(const TracingServiceState_Producer& other) const { return !(*this == other); }
14588 
14589   bool ParseFromArray(const void*, size_t) override;
14590   std::string SerializeAsString() const override;
14591   std::vector<uint8_t> SerializeAsArray() const override;
14592   void Serialize(::protozero::Message*) const;
14593 
has_id() const14594   bool has_id() const { return _has_field_[1]; }
id() const14595   int32_t id() const { return id_; }
set_id(int32_t value)14596   void set_id(int32_t value) { id_ = value; _has_field_.set(1); }
14597 
has_name() const14598   bool has_name() const { return _has_field_[2]; }
name() const14599   const std::string& name() const { return name_; }
set_name(const std::string & value)14600   void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
14601 
has_uid() const14602   bool has_uid() const { return _has_field_[3]; }
uid() const14603   int32_t uid() const { return uid_; }
set_uid(int32_t value)14604   void set_uid(int32_t value) { uid_ = value; _has_field_.set(3); }
14605 
has_sdk_version() const14606   bool has_sdk_version() const { return _has_field_[4]; }
sdk_version() const14607   const std::string& sdk_version() const { return sdk_version_; }
set_sdk_version(const std::string & value)14608   void set_sdk_version(const std::string& value) { sdk_version_ = value; _has_field_.set(4); }
14609 
14610  private:
14611   int32_t id_{};
14612   std::string name_{};
14613   int32_t uid_{};
14614   std::string sdk_version_{};
14615 
14616   // Allows to preserve unknown protobuf fields for compatibility
14617   // with future versions of .proto files.
14618   std::string unknown_fields_;
14619 
14620   std::bitset<5> _has_field_{};
14621 };
14622 
14623 }  // namespace perfetto
14624 }  // namespace protos
14625 }  // namespace gen
14626 
14627 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_STATE_PROTO_CPP_H_
14628 // gen_amalgamated begin header: gen/protos/perfetto/common/track_event_descriptor.gen.h
14629 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
14630 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACK_EVENT_DESCRIPTOR_PROTO_CPP_H_
14631 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACK_EVENT_DESCRIPTOR_PROTO_CPP_H_
14632 
14633 #include <stdint.h>
14634 #include <bitset>
14635 #include <vector>
14636 #include <string>
14637 #include <type_traits>
14638 
14639 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
14640 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
14641 // gen_amalgamated expanded: #include "perfetto/base/export.h"
14642 
14643 namespace perfetto {
14644 namespace protos {
14645 namespace gen {
14646 class TrackEventDescriptor;
14647 class TrackEventCategory;
14648 }  // namespace perfetto
14649 }  // namespace protos
14650 }  // namespace gen
14651 
14652 namespace protozero {
14653 class Message;
14654 }  // namespace protozero
14655 
14656 namespace perfetto {
14657 namespace protos {
14658 namespace gen {
14659 
14660 class PERFETTO_EXPORT TrackEventDescriptor : public ::protozero::CppMessageObj {
14661  public:
14662   enum FieldNumbers {
14663     kAvailableCategoriesFieldNumber = 1,
14664   };
14665 
14666   TrackEventDescriptor();
14667   ~TrackEventDescriptor() override;
14668   TrackEventDescriptor(TrackEventDescriptor&&) noexcept;
14669   TrackEventDescriptor& operator=(TrackEventDescriptor&&);
14670   TrackEventDescriptor(const TrackEventDescriptor&);
14671   TrackEventDescriptor& operator=(const TrackEventDescriptor&);
14672   bool operator==(const TrackEventDescriptor&) const;
operator !=(const TrackEventDescriptor & other) const14673   bool operator!=(const TrackEventDescriptor& other) const { return !(*this == other); }
14674 
14675   bool ParseFromArray(const void*, size_t) override;
14676   std::string SerializeAsString() const override;
14677   std::vector<uint8_t> SerializeAsArray() const override;
14678   void Serialize(::protozero::Message*) const;
14679 
available_categories() const14680   const std::vector<TrackEventCategory>& available_categories() const { return available_categories_; }
mutable_available_categories()14681   std::vector<TrackEventCategory>* mutable_available_categories() { return &available_categories_; }
14682   int available_categories_size() const;
14683   void clear_available_categories();
14684   TrackEventCategory* add_available_categories();
14685 
14686  private:
14687   std::vector<TrackEventCategory> available_categories_;
14688 
14689   // Allows to preserve unknown protobuf fields for compatibility
14690   // with future versions of .proto files.
14691   std::string unknown_fields_;
14692 
14693   std::bitset<2> _has_field_{};
14694 };
14695 
14696 
14697 class PERFETTO_EXPORT TrackEventCategory : public ::protozero::CppMessageObj {
14698  public:
14699   enum FieldNumbers {
14700     kNameFieldNumber = 1,
14701     kDescriptionFieldNumber = 2,
14702     kTagsFieldNumber = 3,
14703   };
14704 
14705   TrackEventCategory();
14706   ~TrackEventCategory() override;
14707   TrackEventCategory(TrackEventCategory&&) noexcept;
14708   TrackEventCategory& operator=(TrackEventCategory&&);
14709   TrackEventCategory(const TrackEventCategory&);
14710   TrackEventCategory& operator=(const TrackEventCategory&);
14711   bool operator==(const TrackEventCategory&) const;
operator !=(const TrackEventCategory & other) const14712   bool operator!=(const TrackEventCategory& other) const { return !(*this == other); }
14713 
14714   bool ParseFromArray(const void*, size_t) override;
14715   std::string SerializeAsString() const override;
14716   std::vector<uint8_t> SerializeAsArray() const override;
14717   void Serialize(::protozero::Message*) const;
14718 
has_name() const14719   bool has_name() const { return _has_field_[1]; }
name() const14720   const std::string& name() const { return name_; }
set_name(const std::string & value)14721   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
14722 
has_description() const14723   bool has_description() const { return _has_field_[2]; }
description() const14724   const std::string& description() const { return description_; }
set_description(const std::string & value)14725   void set_description(const std::string& value) { description_ = value; _has_field_.set(2); }
14726 
tags() const14727   const std::vector<std::string>& tags() const { return tags_; }
mutable_tags()14728   std::vector<std::string>* mutable_tags() { return &tags_; }
tags_size() const14729   int tags_size() const { return static_cast<int>(tags_.size()); }
clear_tags()14730   void clear_tags() { tags_.clear(); }
add_tags(std::string value)14731   void add_tags(std::string value) { tags_.emplace_back(value); }
add_tags()14732   std::string* add_tags() { tags_.emplace_back(); return &tags_.back(); }
14733 
14734  private:
14735   std::string name_{};
14736   std::string description_{};
14737   std::vector<std::string> tags_;
14738 
14739   // Allows to preserve unknown protobuf fields for compatibility
14740   // with future versions of .proto files.
14741   std::string unknown_fields_;
14742 
14743   std::bitset<4> _has_field_{};
14744 };
14745 
14746 }  // namespace perfetto
14747 }  // namespace protos
14748 }  // namespace gen
14749 
14750 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACK_EVENT_DESCRIPTOR_PROTO_CPP_H_
14751 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
14752 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
14753 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
14754 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
14755 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
14756 #if defined(__GNUC__) || defined(__clang__)
14757 #pragma GCC diagnostic push
14758 #pragma GCC diagnostic ignored "-Wfloat-equal"
14759 #endif
14760 // gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_state.gen.h"
14761 // gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
14762 // gen_amalgamated expanded: #include "protos/perfetto/common/track_event_descriptor.gen.h"
14763 // gen_amalgamated expanded: #include "protos/perfetto/common/gpu_counter_descriptor.gen.h"
14764 
14765 namespace perfetto {
14766 namespace protos {
14767 namespace gen {
14768 
14769 TracingServiceState::TracingServiceState() = default;
14770 TracingServiceState::~TracingServiceState() = default;
14771 TracingServiceState::TracingServiceState(const TracingServiceState&) = default;
14772 TracingServiceState& TracingServiceState::operator=(const TracingServiceState&) = default;
14773 TracingServiceState::TracingServiceState(TracingServiceState&&) noexcept = default;
14774 TracingServiceState& TracingServiceState::operator=(TracingServiceState&&) = default;
14775 
operator ==(const TracingServiceState & other) const14776 bool TracingServiceState::operator==(const TracingServiceState& other) const {
14777   return unknown_fields_ == other.unknown_fields_
14778    && producers_ == other.producers_
14779    && data_sources_ == other.data_sources_
14780    && num_sessions_ == other.num_sessions_
14781    && num_sessions_started_ == other.num_sessions_started_
14782    && tracing_service_version_ == other.tracing_service_version_;
14783 }
14784 
producers_size() const14785 int TracingServiceState::producers_size() const { return static_cast<int>(producers_.size()); }
clear_producers()14786 void TracingServiceState::clear_producers() { producers_.clear(); }
add_producers()14787 TracingServiceState_Producer* TracingServiceState::add_producers() { producers_.emplace_back(); return &producers_.back(); }
data_sources_size() const14788 int TracingServiceState::data_sources_size() const { return static_cast<int>(data_sources_.size()); }
clear_data_sources()14789 void TracingServiceState::clear_data_sources() { data_sources_.clear(); }
add_data_sources()14790 TracingServiceState_DataSource* TracingServiceState::add_data_sources() { data_sources_.emplace_back(); return &data_sources_.back(); }
ParseFromArray(const void * raw,size_t size)14791 bool TracingServiceState::ParseFromArray(const void* raw, size_t size) {
14792   producers_.clear();
14793   data_sources_.clear();
14794   unknown_fields_.clear();
14795   bool packed_error = false;
14796 
14797   ::protozero::ProtoDecoder dec(raw, size);
14798   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
14799     if (field.id() < _has_field_.size()) {
14800       _has_field_.set(field.id());
14801     }
14802     switch (field.id()) {
14803       case 1 /* producers */:
14804         producers_.emplace_back();
14805         producers_.back().ParseFromArray(field.data(), field.size());
14806         break;
14807       case 2 /* data_sources */:
14808         data_sources_.emplace_back();
14809         data_sources_.back().ParseFromArray(field.data(), field.size());
14810         break;
14811       case 3 /* num_sessions */:
14812         field.get(&num_sessions_);
14813         break;
14814       case 4 /* num_sessions_started */:
14815         field.get(&num_sessions_started_);
14816         break;
14817       case 5 /* tracing_service_version */:
14818         field.get(&tracing_service_version_);
14819         break;
14820       default:
14821         field.SerializeAndAppendTo(&unknown_fields_);
14822         break;
14823     }
14824   }
14825   return !packed_error && !dec.bytes_left();
14826 }
14827 
SerializeAsString() const14828 std::string TracingServiceState::SerializeAsString() const {
14829   ::protozero::HeapBuffered<::protozero::Message> msg;
14830   Serialize(msg.get());
14831   return msg.SerializeAsString();
14832 }
14833 
SerializeAsArray() const14834 std::vector<uint8_t> TracingServiceState::SerializeAsArray() const {
14835   ::protozero::HeapBuffered<::protozero::Message> msg;
14836   Serialize(msg.get());
14837   return msg.SerializeAsArray();
14838 }
14839 
Serialize(::protozero::Message * msg) const14840 void TracingServiceState::Serialize(::protozero::Message* msg) const {
14841   // Field 1: producers
14842   for (auto& it : producers_) {
14843     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
14844   }
14845 
14846   // Field 2: data_sources
14847   for (auto& it : data_sources_) {
14848     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
14849   }
14850 
14851   // Field 3: num_sessions
14852   if (_has_field_[3]) {
14853     msg->AppendVarInt(3, num_sessions_);
14854   }
14855 
14856   // Field 4: num_sessions_started
14857   if (_has_field_[4]) {
14858     msg->AppendVarInt(4, num_sessions_started_);
14859   }
14860 
14861   // Field 5: tracing_service_version
14862   if (_has_field_[5]) {
14863     msg->AppendString(5, tracing_service_version_);
14864   }
14865 
14866   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
14867 }
14868 
14869 
14870 TracingServiceState_DataSource::TracingServiceState_DataSource() = default;
14871 TracingServiceState_DataSource::~TracingServiceState_DataSource() = default;
14872 TracingServiceState_DataSource::TracingServiceState_DataSource(const TracingServiceState_DataSource&) = default;
14873 TracingServiceState_DataSource& TracingServiceState_DataSource::operator=(const TracingServiceState_DataSource&) = default;
14874 TracingServiceState_DataSource::TracingServiceState_DataSource(TracingServiceState_DataSource&&) noexcept = default;
14875 TracingServiceState_DataSource& TracingServiceState_DataSource::operator=(TracingServiceState_DataSource&&) = default;
14876 
operator ==(const TracingServiceState_DataSource & other) const14877 bool TracingServiceState_DataSource::operator==(const TracingServiceState_DataSource& other) const {
14878   return unknown_fields_ == other.unknown_fields_
14879    && ds_descriptor_ == other.ds_descriptor_
14880    && producer_id_ == other.producer_id_;
14881 }
14882 
ParseFromArray(const void * raw,size_t size)14883 bool TracingServiceState_DataSource::ParseFromArray(const void* raw, size_t size) {
14884   unknown_fields_.clear();
14885   bool packed_error = false;
14886 
14887   ::protozero::ProtoDecoder dec(raw, size);
14888   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
14889     if (field.id() < _has_field_.size()) {
14890       _has_field_.set(field.id());
14891     }
14892     switch (field.id()) {
14893       case 1 /* ds_descriptor */:
14894         (*ds_descriptor_).ParseFromArray(field.data(), field.size());
14895         break;
14896       case 2 /* producer_id */:
14897         field.get(&producer_id_);
14898         break;
14899       default:
14900         field.SerializeAndAppendTo(&unknown_fields_);
14901         break;
14902     }
14903   }
14904   return !packed_error && !dec.bytes_left();
14905 }
14906 
SerializeAsString() const14907 std::string TracingServiceState_DataSource::SerializeAsString() const {
14908   ::protozero::HeapBuffered<::protozero::Message> msg;
14909   Serialize(msg.get());
14910   return msg.SerializeAsString();
14911 }
14912 
SerializeAsArray() const14913 std::vector<uint8_t> TracingServiceState_DataSource::SerializeAsArray() const {
14914   ::protozero::HeapBuffered<::protozero::Message> msg;
14915   Serialize(msg.get());
14916   return msg.SerializeAsArray();
14917 }
14918 
Serialize(::protozero::Message * msg) const14919 void TracingServiceState_DataSource::Serialize(::protozero::Message* msg) const {
14920   // Field 1: ds_descriptor
14921   if (_has_field_[1]) {
14922     (*ds_descriptor_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
14923   }
14924 
14925   // Field 2: producer_id
14926   if (_has_field_[2]) {
14927     msg->AppendVarInt(2, producer_id_);
14928   }
14929 
14930   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
14931 }
14932 
14933 
14934 TracingServiceState_Producer::TracingServiceState_Producer() = default;
14935 TracingServiceState_Producer::~TracingServiceState_Producer() = default;
14936 TracingServiceState_Producer::TracingServiceState_Producer(const TracingServiceState_Producer&) = default;
14937 TracingServiceState_Producer& TracingServiceState_Producer::operator=(const TracingServiceState_Producer&) = default;
14938 TracingServiceState_Producer::TracingServiceState_Producer(TracingServiceState_Producer&&) noexcept = default;
14939 TracingServiceState_Producer& TracingServiceState_Producer::operator=(TracingServiceState_Producer&&) = default;
14940 
operator ==(const TracingServiceState_Producer & other) const14941 bool TracingServiceState_Producer::operator==(const TracingServiceState_Producer& other) const {
14942   return unknown_fields_ == other.unknown_fields_
14943    && id_ == other.id_
14944    && name_ == other.name_
14945    && uid_ == other.uid_
14946    && sdk_version_ == other.sdk_version_;
14947 }
14948 
ParseFromArray(const void * raw,size_t size)14949 bool TracingServiceState_Producer::ParseFromArray(const void* raw, size_t size) {
14950   unknown_fields_.clear();
14951   bool packed_error = false;
14952 
14953   ::protozero::ProtoDecoder dec(raw, size);
14954   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
14955     if (field.id() < _has_field_.size()) {
14956       _has_field_.set(field.id());
14957     }
14958     switch (field.id()) {
14959       case 1 /* id */:
14960         field.get(&id_);
14961         break;
14962       case 2 /* name */:
14963         field.get(&name_);
14964         break;
14965       case 3 /* uid */:
14966         field.get(&uid_);
14967         break;
14968       case 4 /* sdk_version */:
14969         field.get(&sdk_version_);
14970         break;
14971       default:
14972         field.SerializeAndAppendTo(&unknown_fields_);
14973         break;
14974     }
14975   }
14976   return !packed_error && !dec.bytes_left();
14977 }
14978 
SerializeAsString() const14979 std::string TracingServiceState_Producer::SerializeAsString() const {
14980   ::protozero::HeapBuffered<::protozero::Message> msg;
14981   Serialize(msg.get());
14982   return msg.SerializeAsString();
14983 }
14984 
SerializeAsArray() const14985 std::vector<uint8_t> TracingServiceState_Producer::SerializeAsArray() const {
14986   ::protozero::HeapBuffered<::protozero::Message> msg;
14987   Serialize(msg.get());
14988   return msg.SerializeAsArray();
14989 }
14990 
Serialize(::protozero::Message * msg) const14991 void TracingServiceState_Producer::Serialize(::protozero::Message* msg) const {
14992   // Field 1: id
14993   if (_has_field_[1]) {
14994     msg->AppendVarInt(1, id_);
14995   }
14996 
14997   // Field 2: name
14998   if (_has_field_[2]) {
14999     msg->AppendString(2, name_);
15000   }
15001 
15002   // Field 3: uid
15003   if (_has_field_[3]) {
15004     msg->AppendVarInt(3, uid_);
15005   }
15006 
15007   // Field 4: sdk_version
15008   if (_has_field_[4]) {
15009     msg->AppendString(4, sdk_version_);
15010   }
15011 
15012   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
15013 }
15014 
15015 }  // namespace perfetto
15016 }  // namespace protos
15017 }  // namespace gen
15018 #if defined(__GNUC__) || defined(__clang__)
15019 #pragma GCC diagnostic pop
15020 #endif
15021 // gen_amalgamated begin source: gen/protos/perfetto/common/track_event_descriptor.gen.cc
15022 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
15023 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
15024 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
15025 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
15026 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
15027 #if defined(__GNUC__) || defined(__clang__)
15028 #pragma GCC diagnostic push
15029 #pragma GCC diagnostic ignored "-Wfloat-equal"
15030 #endif
15031 // gen_amalgamated expanded: #include "protos/perfetto/common/track_event_descriptor.gen.h"
15032 
15033 namespace perfetto {
15034 namespace protos {
15035 namespace gen {
15036 
15037 TrackEventDescriptor::TrackEventDescriptor() = default;
15038 TrackEventDescriptor::~TrackEventDescriptor() = default;
15039 TrackEventDescriptor::TrackEventDescriptor(const TrackEventDescriptor&) = default;
15040 TrackEventDescriptor& TrackEventDescriptor::operator=(const TrackEventDescriptor&) = default;
15041 TrackEventDescriptor::TrackEventDescriptor(TrackEventDescriptor&&) noexcept = default;
15042 TrackEventDescriptor& TrackEventDescriptor::operator=(TrackEventDescriptor&&) = default;
15043 
operator ==(const TrackEventDescriptor & other) const15044 bool TrackEventDescriptor::operator==(const TrackEventDescriptor& other) const {
15045   return unknown_fields_ == other.unknown_fields_
15046    && available_categories_ == other.available_categories_;
15047 }
15048 
available_categories_size() const15049 int TrackEventDescriptor::available_categories_size() const { return static_cast<int>(available_categories_.size()); }
clear_available_categories()15050 void TrackEventDescriptor::clear_available_categories() { available_categories_.clear(); }
add_available_categories()15051 TrackEventCategory* TrackEventDescriptor::add_available_categories() { available_categories_.emplace_back(); return &available_categories_.back(); }
ParseFromArray(const void * raw,size_t size)15052 bool TrackEventDescriptor::ParseFromArray(const void* raw, size_t size) {
15053   available_categories_.clear();
15054   unknown_fields_.clear();
15055   bool packed_error = false;
15056 
15057   ::protozero::ProtoDecoder dec(raw, size);
15058   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
15059     if (field.id() < _has_field_.size()) {
15060       _has_field_.set(field.id());
15061     }
15062     switch (field.id()) {
15063       case 1 /* available_categories */:
15064         available_categories_.emplace_back();
15065         available_categories_.back().ParseFromArray(field.data(), field.size());
15066         break;
15067       default:
15068         field.SerializeAndAppendTo(&unknown_fields_);
15069         break;
15070     }
15071   }
15072   return !packed_error && !dec.bytes_left();
15073 }
15074 
SerializeAsString() const15075 std::string TrackEventDescriptor::SerializeAsString() const {
15076   ::protozero::HeapBuffered<::protozero::Message> msg;
15077   Serialize(msg.get());
15078   return msg.SerializeAsString();
15079 }
15080 
SerializeAsArray() const15081 std::vector<uint8_t> TrackEventDescriptor::SerializeAsArray() const {
15082   ::protozero::HeapBuffered<::protozero::Message> msg;
15083   Serialize(msg.get());
15084   return msg.SerializeAsArray();
15085 }
15086 
Serialize(::protozero::Message * msg) const15087 void TrackEventDescriptor::Serialize(::protozero::Message* msg) const {
15088   // Field 1: available_categories
15089   for (auto& it : available_categories_) {
15090     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
15091   }
15092 
15093   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
15094 }
15095 
15096 
15097 TrackEventCategory::TrackEventCategory() = default;
15098 TrackEventCategory::~TrackEventCategory() = default;
15099 TrackEventCategory::TrackEventCategory(const TrackEventCategory&) = default;
15100 TrackEventCategory& TrackEventCategory::operator=(const TrackEventCategory&) = default;
15101 TrackEventCategory::TrackEventCategory(TrackEventCategory&&) noexcept = default;
15102 TrackEventCategory& TrackEventCategory::operator=(TrackEventCategory&&) = default;
15103 
operator ==(const TrackEventCategory & other) const15104 bool TrackEventCategory::operator==(const TrackEventCategory& other) const {
15105   return unknown_fields_ == other.unknown_fields_
15106    && name_ == other.name_
15107    && description_ == other.description_
15108    && tags_ == other.tags_;
15109 }
15110 
ParseFromArray(const void * raw,size_t size)15111 bool TrackEventCategory::ParseFromArray(const void* raw, size_t size) {
15112   tags_.clear();
15113   unknown_fields_.clear();
15114   bool packed_error = false;
15115 
15116   ::protozero::ProtoDecoder dec(raw, size);
15117   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
15118     if (field.id() < _has_field_.size()) {
15119       _has_field_.set(field.id());
15120     }
15121     switch (field.id()) {
15122       case 1 /* name */:
15123         field.get(&name_);
15124         break;
15125       case 2 /* description */:
15126         field.get(&description_);
15127         break;
15128       case 3 /* tags */:
15129         tags_.emplace_back();
15130         field.get(&tags_.back());
15131         break;
15132       default:
15133         field.SerializeAndAppendTo(&unknown_fields_);
15134         break;
15135     }
15136   }
15137   return !packed_error && !dec.bytes_left();
15138 }
15139 
SerializeAsString() const15140 std::string TrackEventCategory::SerializeAsString() const {
15141   ::protozero::HeapBuffered<::protozero::Message> msg;
15142   Serialize(msg.get());
15143   return msg.SerializeAsString();
15144 }
15145 
SerializeAsArray() const15146 std::vector<uint8_t> TrackEventCategory::SerializeAsArray() const {
15147   ::protozero::HeapBuffered<::protozero::Message> msg;
15148   Serialize(msg.get());
15149   return msg.SerializeAsArray();
15150 }
15151 
Serialize(::protozero::Message * msg) const15152 void TrackEventCategory::Serialize(::protozero::Message* msg) const {
15153   // Field 1: name
15154   if (_has_field_[1]) {
15155     msg->AppendString(1, name_);
15156   }
15157 
15158   // Field 2: description
15159   if (_has_field_[2]) {
15160     msg->AppendString(2, description_);
15161   }
15162 
15163   // Field 3: tags
15164   for (auto& it : tags_) {
15165     msg->AppendString(3, it);
15166   }
15167 
15168   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
15169 }
15170 
15171 }  // namespace perfetto
15172 }  // namespace protos
15173 }  // namespace gen
15174 #if defined(__GNUC__) || defined(__clang__)
15175 #pragma GCC diagnostic pop
15176 #endif
15177 // gen_amalgamated begin source: gen/protos/perfetto/config/android/android_log_config.gen.cc
15178 // gen_amalgamated begin header: gen/protos/perfetto/config/android/android_log_config.gen.h
15179 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
15180 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_LOG_CONFIG_PROTO_CPP_H_
15181 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_LOG_CONFIG_PROTO_CPP_H_
15182 
15183 #include <stdint.h>
15184 #include <bitset>
15185 #include <vector>
15186 #include <string>
15187 #include <type_traits>
15188 
15189 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
15190 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
15191 // gen_amalgamated expanded: #include "perfetto/base/export.h"
15192 
15193 namespace perfetto {
15194 namespace protos {
15195 namespace gen {
15196 class AndroidLogConfig;
15197 enum AndroidLogId : int;
15198 enum AndroidLogPriority : int;
15199 }  // namespace perfetto
15200 }  // namespace protos
15201 }  // namespace gen
15202 
15203 namespace protozero {
15204 class Message;
15205 }  // namespace protozero
15206 
15207 namespace perfetto {
15208 namespace protos {
15209 namespace gen {
15210 
15211 class PERFETTO_EXPORT AndroidLogConfig : public ::protozero::CppMessageObj {
15212  public:
15213   enum FieldNumbers {
15214     kLogIdsFieldNumber = 1,
15215     kMinPrioFieldNumber = 3,
15216     kFilterTagsFieldNumber = 4,
15217   };
15218 
15219   AndroidLogConfig();
15220   ~AndroidLogConfig() override;
15221   AndroidLogConfig(AndroidLogConfig&&) noexcept;
15222   AndroidLogConfig& operator=(AndroidLogConfig&&);
15223   AndroidLogConfig(const AndroidLogConfig&);
15224   AndroidLogConfig& operator=(const AndroidLogConfig&);
15225   bool operator==(const AndroidLogConfig&) const;
operator !=(const AndroidLogConfig & other) const15226   bool operator!=(const AndroidLogConfig& other) const { return !(*this == other); }
15227 
15228   bool ParseFromArray(const void*, size_t) override;
15229   std::string SerializeAsString() const override;
15230   std::vector<uint8_t> SerializeAsArray() const override;
15231   void Serialize(::protozero::Message*) const;
15232 
log_ids() const15233   const std::vector<AndroidLogId>& log_ids() const { return log_ids_; }
mutable_log_ids()15234   std::vector<AndroidLogId>* mutable_log_ids() { return &log_ids_; }
log_ids_size() const15235   int log_ids_size() const { return static_cast<int>(log_ids_.size()); }
clear_log_ids()15236   void clear_log_ids() { log_ids_.clear(); }
add_log_ids(AndroidLogId value)15237   void add_log_ids(AndroidLogId value) { log_ids_.emplace_back(value); }
add_log_ids()15238   AndroidLogId* add_log_ids() { log_ids_.emplace_back(); return &log_ids_.back(); }
15239 
has_min_prio() const15240   bool has_min_prio() const { return _has_field_[3]; }
min_prio() const15241   AndroidLogPriority min_prio() const { return min_prio_; }
set_min_prio(AndroidLogPriority value)15242   void set_min_prio(AndroidLogPriority value) { min_prio_ = value; _has_field_.set(3); }
15243 
filter_tags() const15244   const std::vector<std::string>& filter_tags() const { return filter_tags_; }
mutable_filter_tags()15245   std::vector<std::string>* mutable_filter_tags() { return &filter_tags_; }
filter_tags_size() const15246   int filter_tags_size() const { return static_cast<int>(filter_tags_.size()); }
clear_filter_tags()15247   void clear_filter_tags() { filter_tags_.clear(); }
add_filter_tags(std::string value)15248   void add_filter_tags(std::string value) { filter_tags_.emplace_back(value); }
add_filter_tags()15249   std::string* add_filter_tags() { filter_tags_.emplace_back(); return &filter_tags_.back(); }
15250 
15251  private:
15252   std::vector<AndroidLogId> log_ids_;
15253   AndroidLogPriority min_prio_{};
15254   std::vector<std::string> filter_tags_;
15255 
15256   // Allows to preserve unknown protobuf fields for compatibility
15257   // with future versions of .proto files.
15258   std::string unknown_fields_;
15259 
15260   std::bitset<5> _has_field_{};
15261 };
15262 
15263 }  // namespace perfetto
15264 }  // namespace protos
15265 }  // namespace gen
15266 
15267 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_LOG_CONFIG_PROTO_CPP_H_
15268 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
15269 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
15270 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
15271 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
15272 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
15273 #if defined(__GNUC__) || defined(__clang__)
15274 #pragma GCC diagnostic push
15275 #pragma GCC diagnostic ignored "-Wfloat-equal"
15276 #endif
15277 // gen_amalgamated expanded: #include "protos/perfetto/config/android/android_log_config.gen.h"
15278 // gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
15279 
15280 namespace perfetto {
15281 namespace protos {
15282 namespace gen {
15283 
15284 AndroidLogConfig::AndroidLogConfig() = default;
15285 AndroidLogConfig::~AndroidLogConfig() = default;
15286 AndroidLogConfig::AndroidLogConfig(const AndroidLogConfig&) = default;
15287 AndroidLogConfig& AndroidLogConfig::operator=(const AndroidLogConfig&) = default;
15288 AndroidLogConfig::AndroidLogConfig(AndroidLogConfig&&) noexcept = default;
15289 AndroidLogConfig& AndroidLogConfig::operator=(AndroidLogConfig&&) = default;
15290 
operator ==(const AndroidLogConfig & other) const15291 bool AndroidLogConfig::operator==(const AndroidLogConfig& other) const {
15292   return unknown_fields_ == other.unknown_fields_
15293    && log_ids_ == other.log_ids_
15294    && min_prio_ == other.min_prio_
15295    && filter_tags_ == other.filter_tags_;
15296 }
15297 
ParseFromArray(const void * raw,size_t size)15298 bool AndroidLogConfig::ParseFromArray(const void* raw, size_t size) {
15299   log_ids_.clear();
15300   filter_tags_.clear();
15301   unknown_fields_.clear();
15302   bool packed_error = false;
15303 
15304   ::protozero::ProtoDecoder dec(raw, size);
15305   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
15306     if (field.id() < _has_field_.size()) {
15307       _has_field_.set(field.id());
15308     }
15309     switch (field.id()) {
15310       case 1 /* log_ids */:
15311         log_ids_.emplace_back();
15312         field.get(&log_ids_.back());
15313         break;
15314       case 3 /* min_prio */:
15315         field.get(&min_prio_);
15316         break;
15317       case 4 /* filter_tags */:
15318         filter_tags_.emplace_back();
15319         field.get(&filter_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 AndroidLogConfig::SerializeAsString() const {
15330   ::protozero::HeapBuffered<::protozero::Message> msg;
15331   Serialize(msg.get());
15332   return msg.SerializeAsString();
15333 }
15334 
SerializeAsArray() const15335 std::vector<uint8_t> AndroidLogConfig::SerializeAsArray() const {
15336   ::protozero::HeapBuffered<::protozero::Message> msg;
15337   Serialize(msg.get());
15338   return msg.SerializeAsArray();
15339 }
15340 
Serialize(::protozero::Message * msg) const15341 void AndroidLogConfig::Serialize(::protozero::Message* msg) const {
15342   // Field 1: log_ids
15343   for (auto& it : log_ids_) {
15344     msg->AppendVarInt(1, it);
15345   }
15346 
15347   // Field 3: min_prio
15348   if (_has_field_[3]) {
15349     msg->AppendVarInt(3, min_prio_);
15350   }
15351 
15352   // Field 4: filter_tags
15353   for (auto& it : filter_tags_) {
15354     msg->AppendString(4, it);
15355   }
15356 
15357   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
15358 }
15359 
15360 }  // namespace perfetto
15361 }  // namespace protos
15362 }  // namespace gen
15363 #if defined(__GNUC__) || defined(__clang__)
15364 #pragma GCC diagnostic pop
15365 #endif
15366 // gen_amalgamated begin source: gen/protos/perfetto/config/android/android_polled_state_config.gen.cc
15367 // gen_amalgamated begin header: gen/protos/perfetto/config/android/android_polled_state_config.gen.h
15368 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
15369 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_POLLED_STATE_CONFIG_PROTO_CPP_H_
15370 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_POLLED_STATE_CONFIG_PROTO_CPP_H_
15371 
15372 #include <stdint.h>
15373 #include <bitset>
15374 #include <vector>
15375 #include <string>
15376 #include <type_traits>
15377 
15378 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
15379 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
15380 // gen_amalgamated expanded: #include "perfetto/base/export.h"
15381 
15382 namespace perfetto {
15383 namespace protos {
15384 namespace gen {
15385 class AndroidPolledStateConfig;
15386 }  // namespace perfetto
15387 }  // namespace protos
15388 }  // namespace gen
15389 
15390 namespace protozero {
15391 class Message;
15392 }  // namespace protozero
15393 
15394 namespace perfetto {
15395 namespace protos {
15396 namespace gen {
15397 
15398 class PERFETTO_EXPORT AndroidPolledStateConfig : public ::protozero::CppMessageObj {
15399  public:
15400   enum FieldNumbers {
15401     kPollMsFieldNumber = 1,
15402   };
15403 
15404   AndroidPolledStateConfig();
15405   ~AndroidPolledStateConfig() override;
15406   AndroidPolledStateConfig(AndroidPolledStateConfig&&) noexcept;
15407   AndroidPolledStateConfig& operator=(AndroidPolledStateConfig&&);
15408   AndroidPolledStateConfig(const AndroidPolledStateConfig&);
15409   AndroidPolledStateConfig& operator=(const AndroidPolledStateConfig&);
15410   bool operator==(const AndroidPolledStateConfig&) const;
operator !=(const AndroidPolledStateConfig & other) const15411   bool operator!=(const AndroidPolledStateConfig& other) const { return !(*this == other); }
15412 
15413   bool ParseFromArray(const void*, size_t) override;
15414   std::string SerializeAsString() const override;
15415   std::vector<uint8_t> SerializeAsArray() const override;
15416   void Serialize(::protozero::Message*) const;
15417 
has_poll_ms() const15418   bool has_poll_ms() const { return _has_field_[1]; }
poll_ms() const15419   uint32_t poll_ms() const { return poll_ms_; }
set_poll_ms(uint32_t value)15420   void set_poll_ms(uint32_t value) { poll_ms_ = value; _has_field_.set(1); }
15421 
15422  private:
15423   uint32_t poll_ms_{};
15424 
15425   // Allows to preserve unknown protobuf fields for compatibility
15426   // with future versions of .proto files.
15427   std::string unknown_fields_;
15428 
15429   std::bitset<2> _has_field_{};
15430 };
15431 
15432 }  // namespace perfetto
15433 }  // namespace protos
15434 }  // namespace gen
15435 
15436 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_POLLED_STATE_CONFIG_PROTO_CPP_H_
15437 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
15438 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
15439 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
15440 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
15441 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
15442 #if defined(__GNUC__) || defined(__clang__)
15443 #pragma GCC diagnostic push
15444 #pragma GCC diagnostic ignored "-Wfloat-equal"
15445 #endif
15446 // gen_amalgamated expanded: #include "protos/perfetto/config/android/android_polled_state_config.gen.h"
15447 
15448 namespace perfetto {
15449 namespace protos {
15450 namespace gen {
15451 
15452 AndroidPolledStateConfig::AndroidPolledStateConfig() = default;
15453 AndroidPolledStateConfig::~AndroidPolledStateConfig() = default;
15454 AndroidPolledStateConfig::AndroidPolledStateConfig(const AndroidPolledStateConfig&) = default;
15455 AndroidPolledStateConfig& AndroidPolledStateConfig::operator=(const AndroidPolledStateConfig&) = default;
15456 AndroidPolledStateConfig::AndroidPolledStateConfig(AndroidPolledStateConfig&&) noexcept = default;
15457 AndroidPolledStateConfig& AndroidPolledStateConfig::operator=(AndroidPolledStateConfig&&) = default;
15458 
operator ==(const AndroidPolledStateConfig & other) const15459 bool AndroidPolledStateConfig::operator==(const AndroidPolledStateConfig& other) const {
15460   return unknown_fields_ == other.unknown_fields_
15461    && poll_ms_ == other.poll_ms_;
15462 }
15463 
ParseFromArray(const void * raw,size_t size)15464 bool AndroidPolledStateConfig::ParseFromArray(const void* raw, size_t size) {
15465   unknown_fields_.clear();
15466   bool packed_error = false;
15467 
15468   ::protozero::ProtoDecoder dec(raw, size);
15469   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
15470     if (field.id() < _has_field_.size()) {
15471       _has_field_.set(field.id());
15472     }
15473     switch (field.id()) {
15474       case 1 /* poll_ms */:
15475         field.get(&poll_ms_);
15476         break;
15477       default:
15478         field.SerializeAndAppendTo(&unknown_fields_);
15479         break;
15480     }
15481   }
15482   return !packed_error && !dec.bytes_left();
15483 }
15484 
SerializeAsString() const15485 std::string AndroidPolledStateConfig::SerializeAsString() const {
15486   ::protozero::HeapBuffered<::protozero::Message> msg;
15487   Serialize(msg.get());
15488   return msg.SerializeAsString();
15489 }
15490 
SerializeAsArray() const15491 std::vector<uint8_t> AndroidPolledStateConfig::SerializeAsArray() const {
15492   ::protozero::HeapBuffered<::protozero::Message> msg;
15493   Serialize(msg.get());
15494   return msg.SerializeAsArray();
15495 }
15496 
Serialize(::protozero::Message * msg) const15497 void AndroidPolledStateConfig::Serialize(::protozero::Message* msg) const {
15498   // Field 1: poll_ms
15499   if (_has_field_[1]) {
15500     msg->AppendVarInt(1, poll_ms_);
15501   }
15502 
15503   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
15504 }
15505 
15506 }  // namespace perfetto
15507 }  // namespace protos
15508 }  // namespace gen
15509 #if defined(__GNUC__) || defined(__clang__)
15510 #pragma GCC diagnostic pop
15511 #endif
15512 // gen_amalgamated begin source: gen/protos/perfetto/config/android/packages_list_config.gen.cc
15513 // gen_amalgamated begin header: gen/protos/perfetto/config/android/packages_list_config.gen.h
15514 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
15515 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_PACKAGES_LIST_CONFIG_PROTO_CPP_H_
15516 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_PACKAGES_LIST_CONFIG_PROTO_CPP_H_
15517 
15518 #include <stdint.h>
15519 #include <bitset>
15520 #include <vector>
15521 #include <string>
15522 #include <type_traits>
15523 
15524 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
15525 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
15526 // gen_amalgamated expanded: #include "perfetto/base/export.h"
15527 
15528 namespace perfetto {
15529 namespace protos {
15530 namespace gen {
15531 class PackagesListConfig;
15532 }  // namespace perfetto
15533 }  // namespace protos
15534 }  // namespace gen
15535 
15536 namespace protozero {
15537 class Message;
15538 }  // namespace protozero
15539 
15540 namespace perfetto {
15541 namespace protos {
15542 namespace gen {
15543 
15544 class PERFETTO_EXPORT PackagesListConfig : public ::protozero::CppMessageObj {
15545  public:
15546   enum FieldNumbers {
15547     kPackageNameFilterFieldNumber = 1,
15548   };
15549 
15550   PackagesListConfig();
15551   ~PackagesListConfig() override;
15552   PackagesListConfig(PackagesListConfig&&) noexcept;
15553   PackagesListConfig& operator=(PackagesListConfig&&);
15554   PackagesListConfig(const PackagesListConfig&);
15555   PackagesListConfig& operator=(const PackagesListConfig&);
15556   bool operator==(const PackagesListConfig&) const;
operator !=(const PackagesListConfig & other) const15557   bool operator!=(const PackagesListConfig& other) const { return !(*this == other); }
15558 
15559   bool ParseFromArray(const void*, size_t) override;
15560   std::string SerializeAsString() const override;
15561   std::vector<uint8_t> SerializeAsArray() const override;
15562   void Serialize(::protozero::Message*) const;
15563 
package_name_filter() const15564   const std::vector<std::string>& package_name_filter() const { return package_name_filter_; }
mutable_package_name_filter()15565   std::vector<std::string>* mutable_package_name_filter() { return &package_name_filter_; }
package_name_filter_size() const15566   int package_name_filter_size() const { return static_cast<int>(package_name_filter_.size()); }
clear_package_name_filter()15567   void clear_package_name_filter() { package_name_filter_.clear(); }
add_package_name_filter(std::string value)15568   void add_package_name_filter(std::string value) { package_name_filter_.emplace_back(value); }
add_package_name_filter()15569   std::string* add_package_name_filter() { package_name_filter_.emplace_back(); return &package_name_filter_.back(); }
15570 
15571  private:
15572   std::vector<std::string> package_name_filter_;
15573 
15574   // Allows to preserve unknown protobuf fields for compatibility
15575   // with future versions of .proto files.
15576   std::string unknown_fields_;
15577 
15578   std::bitset<2> _has_field_{};
15579 };
15580 
15581 }  // namespace perfetto
15582 }  // namespace protos
15583 }  // namespace gen
15584 
15585 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_PACKAGES_LIST_CONFIG_PROTO_CPP_H_
15586 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
15587 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
15588 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
15589 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
15590 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
15591 #if defined(__GNUC__) || defined(__clang__)
15592 #pragma GCC diagnostic push
15593 #pragma GCC diagnostic ignored "-Wfloat-equal"
15594 #endif
15595 // gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_config.gen.h"
15596 
15597 namespace perfetto {
15598 namespace protos {
15599 namespace gen {
15600 
15601 PackagesListConfig::PackagesListConfig() = default;
15602 PackagesListConfig::~PackagesListConfig() = default;
15603 PackagesListConfig::PackagesListConfig(const PackagesListConfig&) = default;
15604 PackagesListConfig& PackagesListConfig::operator=(const PackagesListConfig&) = default;
15605 PackagesListConfig::PackagesListConfig(PackagesListConfig&&) noexcept = default;
15606 PackagesListConfig& PackagesListConfig::operator=(PackagesListConfig&&) = default;
15607 
operator ==(const PackagesListConfig & other) const15608 bool PackagesListConfig::operator==(const PackagesListConfig& other) const {
15609   return unknown_fields_ == other.unknown_fields_
15610    && package_name_filter_ == other.package_name_filter_;
15611 }
15612 
ParseFromArray(const void * raw,size_t size)15613 bool PackagesListConfig::ParseFromArray(const void* raw, size_t size) {
15614   package_name_filter_.clear();
15615   unknown_fields_.clear();
15616   bool packed_error = false;
15617 
15618   ::protozero::ProtoDecoder dec(raw, size);
15619   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
15620     if (field.id() < _has_field_.size()) {
15621       _has_field_.set(field.id());
15622     }
15623     switch (field.id()) {
15624       case 1 /* package_name_filter */:
15625         package_name_filter_.emplace_back();
15626         field.get(&package_name_filter_.back());
15627         break;
15628       default:
15629         field.SerializeAndAppendTo(&unknown_fields_);
15630         break;
15631     }
15632   }
15633   return !packed_error && !dec.bytes_left();
15634 }
15635 
SerializeAsString() const15636 std::string PackagesListConfig::SerializeAsString() const {
15637   ::protozero::HeapBuffered<::protozero::Message> msg;
15638   Serialize(msg.get());
15639   return msg.SerializeAsString();
15640 }
15641 
SerializeAsArray() const15642 std::vector<uint8_t> PackagesListConfig::SerializeAsArray() const {
15643   ::protozero::HeapBuffered<::protozero::Message> msg;
15644   Serialize(msg.get());
15645   return msg.SerializeAsArray();
15646 }
15647 
Serialize(::protozero::Message * msg) const15648 void PackagesListConfig::Serialize(::protozero::Message* msg) const {
15649   // Field 1: package_name_filter
15650   for (auto& it : package_name_filter_) {
15651     msg->AppendString(1, it);
15652   }
15653 
15654   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
15655 }
15656 
15657 }  // namespace perfetto
15658 }  // namespace protos
15659 }  // namespace gen
15660 #if defined(__GNUC__) || defined(__clang__)
15661 #pragma GCC diagnostic pop
15662 #endif
15663 // gen_amalgamated begin source: gen/protos/perfetto/config/ftrace/ftrace_config.gen.cc
15664 // gen_amalgamated begin header: gen/protos/perfetto/config/ftrace/ftrace_config.gen.h
15665 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
15666 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_FTRACE_FTRACE_CONFIG_PROTO_CPP_H_
15667 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_FTRACE_FTRACE_CONFIG_PROTO_CPP_H_
15668 
15669 #include <stdint.h>
15670 #include <bitset>
15671 #include <vector>
15672 #include <string>
15673 #include <type_traits>
15674 
15675 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
15676 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
15677 // gen_amalgamated expanded: #include "perfetto/base/export.h"
15678 
15679 namespace perfetto {
15680 namespace protos {
15681 namespace gen {
15682 class FtraceConfig;
15683 class FtraceConfig_CompactSchedConfig;
15684 }  // namespace perfetto
15685 }  // namespace protos
15686 }  // namespace gen
15687 
15688 namespace protozero {
15689 class Message;
15690 }  // namespace protozero
15691 
15692 namespace perfetto {
15693 namespace protos {
15694 namespace gen {
15695 
15696 class PERFETTO_EXPORT FtraceConfig : public ::protozero::CppMessageObj {
15697  public:
15698   using CompactSchedConfig = FtraceConfig_CompactSchedConfig;
15699   enum FieldNumbers {
15700     kFtraceEventsFieldNumber = 1,
15701     kAtraceCategoriesFieldNumber = 2,
15702     kAtraceAppsFieldNumber = 3,
15703     kBufferSizeKbFieldNumber = 10,
15704     kDrainPeriodMsFieldNumber = 11,
15705     kCompactSchedFieldNumber = 12,
15706     kSymbolizeKsymsFieldNumber = 13,
15707     kInitializeKsymsSynchronouslyForTestingFieldNumber = 14,
15708   };
15709 
15710   FtraceConfig();
15711   ~FtraceConfig() override;
15712   FtraceConfig(FtraceConfig&&) noexcept;
15713   FtraceConfig& operator=(FtraceConfig&&);
15714   FtraceConfig(const FtraceConfig&);
15715   FtraceConfig& operator=(const FtraceConfig&);
15716   bool operator==(const FtraceConfig&) const;
operator !=(const FtraceConfig & other) const15717   bool operator!=(const FtraceConfig& other) const { return !(*this == other); }
15718 
15719   bool ParseFromArray(const void*, size_t) override;
15720   std::string SerializeAsString() const override;
15721   std::vector<uint8_t> SerializeAsArray() const override;
15722   void Serialize(::protozero::Message*) const;
15723 
ftrace_events() const15724   const std::vector<std::string>& ftrace_events() const { return ftrace_events_; }
mutable_ftrace_events()15725   std::vector<std::string>* mutable_ftrace_events() { return &ftrace_events_; }
ftrace_events_size() const15726   int ftrace_events_size() const { return static_cast<int>(ftrace_events_.size()); }
clear_ftrace_events()15727   void clear_ftrace_events() { ftrace_events_.clear(); }
add_ftrace_events(std::string value)15728   void add_ftrace_events(std::string value) { ftrace_events_.emplace_back(value); }
add_ftrace_events()15729   std::string* add_ftrace_events() { ftrace_events_.emplace_back(); return &ftrace_events_.back(); }
15730 
atrace_categories() const15731   const std::vector<std::string>& atrace_categories() const { return atrace_categories_; }
mutable_atrace_categories()15732   std::vector<std::string>* mutable_atrace_categories() { return &atrace_categories_; }
atrace_categories_size() const15733   int atrace_categories_size() const { return static_cast<int>(atrace_categories_.size()); }
clear_atrace_categories()15734   void clear_atrace_categories() { atrace_categories_.clear(); }
add_atrace_categories(std::string value)15735   void add_atrace_categories(std::string value) { atrace_categories_.emplace_back(value); }
add_atrace_categories()15736   std::string* add_atrace_categories() { atrace_categories_.emplace_back(); return &atrace_categories_.back(); }
15737 
atrace_apps() const15738   const std::vector<std::string>& atrace_apps() const { return atrace_apps_; }
mutable_atrace_apps()15739   std::vector<std::string>* mutable_atrace_apps() { return &atrace_apps_; }
atrace_apps_size() const15740   int atrace_apps_size() const { return static_cast<int>(atrace_apps_.size()); }
clear_atrace_apps()15741   void clear_atrace_apps() { atrace_apps_.clear(); }
add_atrace_apps(std::string value)15742   void add_atrace_apps(std::string value) { atrace_apps_.emplace_back(value); }
add_atrace_apps()15743   std::string* add_atrace_apps() { atrace_apps_.emplace_back(); return &atrace_apps_.back(); }
15744 
has_buffer_size_kb() const15745   bool has_buffer_size_kb() const { return _has_field_[10]; }
buffer_size_kb() const15746   uint32_t buffer_size_kb() const { return buffer_size_kb_; }
set_buffer_size_kb(uint32_t value)15747   void set_buffer_size_kb(uint32_t value) { buffer_size_kb_ = value; _has_field_.set(10); }
15748 
has_drain_period_ms() const15749   bool has_drain_period_ms() const { return _has_field_[11]; }
drain_period_ms() const15750   uint32_t drain_period_ms() const { return drain_period_ms_; }
set_drain_period_ms(uint32_t value)15751   void set_drain_period_ms(uint32_t value) { drain_period_ms_ = value; _has_field_.set(11); }
15752 
has_compact_sched() const15753   bool has_compact_sched() const { return _has_field_[12]; }
compact_sched() const15754   const FtraceConfig_CompactSchedConfig& compact_sched() const { return *compact_sched_; }
mutable_compact_sched()15755   FtraceConfig_CompactSchedConfig* mutable_compact_sched() { _has_field_.set(12); return compact_sched_.get(); }
15756 
has_symbolize_ksyms() const15757   bool has_symbolize_ksyms() const { return _has_field_[13]; }
symbolize_ksyms() const15758   bool symbolize_ksyms() const { return symbolize_ksyms_; }
set_symbolize_ksyms(bool value)15759   void set_symbolize_ksyms(bool value) { symbolize_ksyms_ = value; _has_field_.set(13); }
15760 
has_initialize_ksyms_synchronously_for_testing() const15761   bool has_initialize_ksyms_synchronously_for_testing() const { return _has_field_[14]; }
initialize_ksyms_synchronously_for_testing() const15762   bool initialize_ksyms_synchronously_for_testing() const { return initialize_ksyms_synchronously_for_testing_; }
set_initialize_ksyms_synchronously_for_testing(bool value)15763   void set_initialize_ksyms_synchronously_for_testing(bool value) { initialize_ksyms_synchronously_for_testing_ = value; _has_field_.set(14); }
15764 
15765  private:
15766   std::vector<std::string> ftrace_events_;
15767   std::vector<std::string> atrace_categories_;
15768   std::vector<std::string> atrace_apps_;
15769   uint32_t buffer_size_kb_{};
15770   uint32_t drain_period_ms_{};
15771   ::protozero::CopyablePtr<FtraceConfig_CompactSchedConfig> compact_sched_;
15772   bool symbolize_ksyms_{};
15773   bool initialize_ksyms_synchronously_for_testing_{};
15774 
15775   // Allows to preserve unknown protobuf fields for compatibility
15776   // with future versions of .proto files.
15777   std::string unknown_fields_;
15778 
15779   std::bitset<15> _has_field_{};
15780 };
15781 
15782 
15783 class PERFETTO_EXPORT FtraceConfig_CompactSchedConfig : public ::protozero::CppMessageObj {
15784  public:
15785   enum FieldNumbers {
15786     kEnabledFieldNumber = 1,
15787   };
15788 
15789   FtraceConfig_CompactSchedConfig();
15790   ~FtraceConfig_CompactSchedConfig() override;
15791   FtraceConfig_CompactSchedConfig(FtraceConfig_CompactSchedConfig&&) noexcept;
15792   FtraceConfig_CompactSchedConfig& operator=(FtraceConfig_CompactSchedConfig&&);
15793   FtraceConfig_CompactSchedConfig(const FtraceConfig_CompactSchedConfig&);
15794   FtraceConfig_CompactSchedConfig& operator=(const FtraceConfig_CompactSchedConfig&);
15795   bool operator==(const FtraceConfig_CompactSchedConfig&) const;
operator !=(const FtraceConfig_CompactSchedConfig & other) const15796   bool operator!=(const FtraceConfig_CompactSchedConfig& other) const { return !(*this == other); }
15797 
15798   bool ParseFromArray(const void*, size_t) override;
15799   std::string SerializeAsString() const override;
15800   std::vector<uint8_t> SerializeAsArray() const override;
15801   void Serialize(::protozero::Message*) const;
15802 
has_enabled() const15803   bool has_enabled() const { return _has_field_[1]; }
enabled() const15804   bool enabled() const { return enabled_; }
set_enabled(bool value)15805   void set_enabled(bool value) { enabled_ = value; _has_field_.set(1); }
15806 
15807  private:
15808   bool enabled_{};
15809 
15810   // Allows to preserve unknown protobuf fields for compatibility
15811   // with future versions of .proto files.
15812   std::string unknown_fields_;
15813 
15814   std::bitset<2> _has_field_{};
15815 };
15816 
15817 }  // namespace perfetto
15818 }  // namespace protos
15819 }  // namespace gen
15820 
15821 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_FTRACE_FTRACE_CONFIG_PROTO_CPP_H_
15822 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
15823 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
15824 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
15825 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
15826 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
15827 #if defined(__GNUC__) || defined(__clang__)
15828 #pragma GCC diagnostic push
15829 #pragma GCC diagnostic ignored "-Wfloat-equal"
15830 #endif
15831 // gen_amalgamated expanded: #include "protos/perfetto/config/ftrace/ftrace_config.gen.h"
15832 
15833 namespace perfetto {
15834 namespace protos {
15835 namespace gen {
15836 
15837 FtraceConfig::FtraceConfig() = default;
15838 FtraceConfig::~FtraceConfig() = default;
15839 FtraceConfig::FtraceConfig(const FtraceConfig&) = default;
15840 FtraceConfig& FtraceConfig::operator=(const FtraceConfig&) = default;
15841 FtraceConfig::FtraceConfig(FtraceConfig&&) noexcept = default;
15842 FtraceConfig& FtraceConfig::operator=(FtraceConfig&&) = default;
15843 
operator ==(const FtraceConfig & other) const15844 bool FtraceConfig::operator==(const FtraceConfig& other) const {
15845   return unknown_fields_ == other.unknown_fields_
15846    && ftrace_events_ == other.ftrace_events_
15847    && atrace_categories_ == other.atrace_categories_
15848    && atrace_apps_ == other.atrace_apps_
15849    && buffer_size_kb_ == other.buffer_size_kb_
15850    && drain_period_ms_ == other.drain_period_ms_
15851    && compact_sched_ == other.compact_sched_
15852    && symbolize_ksyms_ == other.symbolize_ksyms_
15853    && initialize_ksyms_synchronously_for_testing_ == other.initialize_ksyms_synchronously_for_testing_;
15854 }
15855 
ParseFromArray(const void * raw,size_t size)15856 bool FtraceConfig::ParseFromArray(const void* raw, size_t size) {
15857   ftrace_events_.clear();
15858   atrace_categories_.clear();
15859   atrace_apps_.clear();
15860   unknown_fields_.clear();
15861   bool packed_error = false;
15862 
15863   ::protozero::ProtoDecoder dec(raw, size);
15864   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
15865     if (field.id() < _has_field_.size()) {
15866       _has_field_.set(field.id());
15867     }
15868     switch (field.id()) {
15869       case 1 /* ftrace_events */:
15870         ftrace_events_.emplace_back();
15871         field.get(&ftrace_events_.back());
15872         break;
15873       case 2 /* atrace_categories */:
15874         atrace_categories_.emplace_back();
15875         field.get(&atrace_categories_.back());
15876         break;
15877       case 3 /* atrace_apps */:
15878         atrace_apps_.emplace_back();
15879         field.get(&atrace_apps_.back());
15880         break;
15881       case 10 /* buffer_size_kb */:
15882         field.get(&buffer_size_kb_);
15883         break;
15884       case 11 /* drain_period_ms */:
15885         field.get(&drain_period_ms_);
15886         break;
15887       case 12 /* compact_sched */:
15888         (*compact_sched_).ParseFromArray(field.data(), field.size());
15889         break;
15890       case 13 /* symbolize_ksyms */:
15891         field.get(&symbolize_ksyms_);
15892         break;
15893       case 14 /* initialize_ksyms_synchronously_for_testing */:
15894         field.get(&initialize_ksyms_synchronously_for_testing_);
15895         break;
15896       default:
15897         field.SerializeAndAppendTo(&unknown_fields_);
15898         break;
15899     }
15900   }
15901   return !packed_error && !dec.bytes_left();
15902 }
15903 
SerializeAsString() const15904 std::string FtraceConfig::SerializeAsString() const {
15905   ::protozero::HeapBuffered<::protozero::Message> msg;
15906   Serialize(msg.get());
15907   return msg.SerializeAsString();
15908 }
15909 
SerializeAsArray() const15910 std::vector<uint8_t> FtraceConfig::SerializeAsArray() const {
15911   ::protozero::HeapBuffered<::protozero::Message> msg;
15912   Serialize(msg.get());
15913   return msg.SerializeAsArray();
15914 }
15915 
Serialize(::protozero::Message * msg) const15916 void FtraceConfig::Serialize(::protozero::Message* msg) const {
15917   // Field 1: ftrace_events
15918   for (auto& it : ftrace_events_) {
15919     msg->AppendString(1, it);
15920   }
15921 
15922   // Field 2: atrace_categories
15923   for (auto& it : atrace_categories_) {
15924     msg->AppendString(2, it);
15925   }
15926 
15927   // Field 3: atrace_apps
15928   for (auto& it : atrace_apps_) {
15929     msg->AppendString(3, it);
15930   }
15931 
15932   // Field 10: buffer_size_kb
15933   if (_has_field_[10]) {
15934     msg->AppendVarInt(10, buffer_size_kb_);
15935   }
15936 
15937   // Field 11: drain_period_ms
15938   if (_has_field_[11]) {
15939     msg->AppendVarInt(11, drain_period_ms_);
15940   }
15941 
15942   // Field 12: compact_sched
15943   if (_has_field_[12]) {
15944     (*compact_sched_).Serialize(msg->BeginNestedMessage<::protozero::Message>(12));
15945   }
15946 
15947   // Field 13: symbolize_ksyms
15948   if (_has_field_[13]) {
15949     msg->AppendTinyVarInt(13, symbolize_ksyms_);
15950   }
15951 
15952   // Field 14: initialize_ksyms_synchronously_for_testing
15953   if (_has_field_[14]) {
15954     msg->AppendTinyVarInt(14, initialize_ksyms_synchronously_for_testing_);
15955   }
15956 
15957   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
15958 }
15959 
15960 
15961 FtraceConfig_CompactSchedConfig::FtraceConfig_CompactSchedConfig() = default;
15962 FtraceConfig_CompactSchedConfig::~FtraceConfig_CompactSchedConfig() = default;
15963 FtraceConfig_CompactSchedConfig::FtraceConfig_CompactSchedConfig(const FtraceConfig_CompactSchedConfig&) = default;
15964 FtraceConfig_CompactSchedConfig& FtraceConfig_CompactSchedConfig::operator=(const FtraceConfig_CompactSchedConfig&) = default;
15965 FtraceConfig_CompactSchedConfig::FtraceConfig_CompactSchedConfig(FtraceConfig_CompactSchedConfig&&) noexcept = default;
15966 FtraceConfig_CompactSchedConfig& FtraceConfig_CompactSchedConfig::operator=(FtraceConfig_CompactSchedConfig&&) = default;
15967 
operator ==(const FtraceConfig_CompactSchedConfig & other) const15968 bool FtraceConfig_CompactSchedConfig::operator==(const FtraceConfig_CompactSchedConfig& other) const {
15969   return unknown_fields_ == other.unknown_fields_
15970    && enabled_ == other.enabled_;
15971 }
15972 
ParseFromArray(const void * raw,size_t size)15973 bool FtraceConfig_CompactSchedConfig::ParseFromArray(const void* raw, size_t size) {
15974   unknown_fields_.clear();
15975   bool packed_error = false;
15976 
15977   ::protozero::ProtoDecoder dec(raw, size);
15978   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
15979     if (field.id() < _has_field_.size()) {
15980       _has_field_.set(field.id());
15981     }
15982     switch (field.id()) {
15983       case 1 /* enabled */:
15984         field.get(&enabled_);
15985         break;
15986       default:
15987         field.SerializeAndAppendTo(&unknown_fields_);
15988         break;
15989     }
15990   }
15991   return !packed_error && !dec.bytes_left();
15992 }
15993 
SerializeAsString() const15994 std::string FtraceConfig_CompactSchedConfig::SerializeAsString() const {
15995   ::protozero::HeapBuffered<::protozero::Message> msg;
15996   Serialize(msg.get());
15997   return msg.SerializeAsString();
15998 }
15999 
SerializeAsArray() const16000 std::vector<uint8_t> FtraceConfig_CompactSchedConfig::SerializeAsArray() const {
16001   ::protozero::HeapBuffered<::protozero::Message> msg;
16002   Serialize(msg.get());
16003   return msg.SerializeAsArray();
16004 }
16005 
Serialize(::protozero::Message * msg) const16006 void FtraceConfig_CompactSchedConfig::Serialize(::protozero::Message* msg) const {
16007   // Field 1: enabled
16008   if (_has_field_[1]) {
16009     msg->AppendTinyVarInt(1, enabled_);
16010   }
16011 
16012   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
16013 }
16014 
16015 }  // namespace perfetto
16016 }  // namespace protos
16017 }  // namespace gen
16018 #if defined(__GNUC__) || defined(__clang__)
16019 #pragma GCC diagnostic pop
16020 #endif
16021 // gen_amalgamated begin source: gen/protos/perfetto/config/gpu/gpu_counter_config.gen.cc
16022 // gen_amalgamated begin header: gen/protos/perfetto/config/gpu/gpu_counter_config.gen.h
16023 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
16024 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_GPU_COUNTER_CONFIG_PROTO_CPP_H_
16025 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_GPU_COUNTER_CONFIG_PROTO_CPP_H_
16026 
16027 #include <stdint.h>
16028 #include <bitset>
16029 #include <vector>
16030 #include <string>
16031 #include <type_traits>
16032 
16033 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
16034 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
16035 // gen_amalgamated expanded: #include "perfetto/base/export.h"
16036 
16037 namespace perfetto {
16038 namespace protos {
16039 namespace gen {
16040 class GpuCounterConfig;
16041 }  // namespace perfetto
16042 }  // namespace protos
16043 }  // namespace gen
16044 
16045 namespace protozero {
16046 class Message;
16047 }  // namespace protozero
16048 
16049 namespace perfetto {
16050 namespace protos {
16051 namespace gen {
16052 
16053 class PERFETTO_EXPORT GpuCounterConfig : public ::protozero::CppMessageObj {
16054  public:
16055   enum FieldNumbers {
16056     kCounterPeriodNsFieldNumber = 1,
16057     kCounterIdsFieldNumber = 2,
16058     kInstrumentedSamplingFieldNumber = 3,
16059     kFixGpuClockFieldNumber = 4,
16060   };
16061 
16062   GpuCounterConfig();
16063   ~GpuCounterConfig() override;
16064   GpuCounterConfig(GpuCounterConfig&&) noexcept;
16065   GpuCounterConfig& operator=(GpuCounterConfig&&);
16066   GpuCounterConfig(const GpuCounterConfig&);
16067   GpuCounterConfig& operator=(const GpuCounterConfig&);
16068   bool operator==(const GpuCounterConfig&) const;
operator !=(const GpuCounterConfig & other) const16069   bool operator!=(const GpuCounterConfig& other) const { return !(*this == other); }
16070 
16071   bool ParseFromArray(const void*, size_t) override;
16072   std::string SerializeAsString() const override;
16073   std::vector<uint8_t> SerializeAsArray() const override;
16074   void Serialize(::protozero::Message*) const;
16075 
has_counter_period_ns() const16076   bool has_counter_period_ns() const { return _has_field_[1]; }
counter_period_ns() const16077   uint64_t counter_period_ns() const { return counter_period_ns_; }
set_counter_period_ns(uint64_t value)16078   void set_counter_period_ns(uint64_t value) { counter_period_ns_ = value; _has_field_.set(1); }
16079 
counter_ids() const16080   const std::vector<uint32_t>& counter_ids() const { return counter_ids_; }
mutable_counter_ids()16081   std::vector<uint32_t>* mutable_counter_ids() { return &counter_ids_; }
counter_ids_size() const16082   int counter_ids_size() const { return static_cast<int>(counter_ids_.size()); }
clear_counter_ids()16083   void clear_counter_ids() { counter_ids_.clear(); }
add_counter_ids(uint32_t value)16084   void add_counter_ids(uint32_t value) { counter_ids_.emplace_back(value); }
add_counter_ids()16085   uint32_t* add_counter_ids() { counter_ids_.emplace_back(); return &counter_ids_.back(); }
16086 
has_instrumented_sampling() const16087   bool has_instrumented_sampling() const { return _has_field_[3]; }
instrumented_sampling() const16088   bool instrumented_sampling() const { return instrumented_sampling_; }
set_instrumented_sampling(bool value)16089   void set_instrumented_sampling(bool value) { instrumented_sampling_ = value; _has_field_.set(3); }
16090 
has_fix_gpu_clock() const16091   bool has_fix_gpu_clock() const { return _has_field_[4]; }
fix_gpu_clock() const16092   bool fix_gpu_clock() const { return fix_gpu_clock_; }
set_fix_gpu_clock(bool value)16093   void set_fix_gpu_clock(bool value) { fix_gpu_clock_ = value; _has_field_.set(4); }
16094 
16095  private:
16096   uint64_t counter_period_ns_{};
16097   std::vector<uint32_t> counter_ids_;
16098   bool instrumented_sampling_{};
16099   bool fix_gpu_clock_{};
16100 
16101   // Allows to preserve unknown protobuf fields for compatibility
16102   // with future versions of .proto files.
16103   std::string unknown_fields_;
16104 
16105   std::bitset<5> _has_field_{};
16106 };
16107 
16108 }  // namespace perfetto
16109 }  // namespace protos
16110 }  // namespace gen
16111 
16112 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_GPU_COUNTER_CONFIG_PROTO_CPP_H_
16113 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
16114 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
16115 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
16116 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
16117 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
16118 #if defined(__GNUC__) || defined(__clang__)
16119 #pragma GCC diagnostic push
16120 #pragma GCC diagnostic ignored "-Wfloat-equal"
16121 #endif
16122 // gen_amalgamated expanded: #include "protos/perfetto/config/gpu/gpu_counter_config.gen.h"
16123 
16124 namespace perfetto {
16125 namespace protos {
16126 namespace gen {
16127 
16128 GpuCounterConfig::GpuCounterConfig() = default;
16129 GpuCounterConfig::~GpuCounterConfig() = default;
16130 GpuCounterConfig::GpuCounterConfig(const GpuCounterConfig&) = default;
16131 GpuCounterConfig& GpuCounterConfig::operator=(const GpuCounterConfig&) = default;
16132 GpuCounterConfig::GpuCounterConfig(GpuCounterConfig&&) noexcept = default;
16133 GpuCounterConfig& GpuCounterConfig::operator=(GpuCounterConfig&&) = default;
16134 
operator ==(const GpuCounterConfig & other) const16135 bool GpuCounterConfig::operator==(const GpuCounterConfig& other) const {
16136   return unknown_fields_ == other.unknown_fields_
16137    && counter_period_ns_ == other.counter_period_ns_
16138    && counter_ids_ == other.counter_ids_
16139    && instrumented_sampling_ == other.instrumented_sampling_
16140    && fix_gpu_clock_ == other.fix_gpu_clock_;
16141 }
16142 
ParseFromArray(const void * raw,size_t size)16143 bool GpuCounterConfig::ParseFromArray(const void* raw, size_t size) {
16144   counter_ids_.clear();
16145   unknown_fields_.clear();
16146   bool packed_error = false;
16147 
16148   ::protozero::ProtoDecoder dec(raw, size);
16149   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
16150     if (field.id() < _has_field_.size()) {
16151       _has_field_.set(field.id());
16152     }
16153     switch (field.id()) {
16154       case 1 /* counter_period_ns */:
16155         field.get(&counter_period_ns_);
16156         break;
16157       case 2 /* counter_ids */:
16158         counter_ids_.emplace_back();
16159         field.get(&counter_ids_.back());
16160         break;
16161       case 3 /* instrumented_sampling */:
16162         field.get(&instrumented_sampling_);
16163         break;
16164       case 4 /* fix_gpu_clock */:
16165         field.get(&fix_gpu_clock_);
16166         break;
16167       default:
16168         field.SerializeAndAppendTo(&unknown_fields_);
16169         break;
16170     }
16171   }
16172   return !packed_error && !dec.bytes_left();
16173 }
16174 
SerializeAsString() const16175 std::string GpuCounterConfig::SerializeAsString() const {
16176   ::protozero::HeapBuffered<::protozero::Message> msg;
16177   Serialize(msg.get());
16178   return msg.SerializeAsString();
16179 }
16180 
SerializeAsArray() const16181 std::vector<uint8_t> GpuCounterConfig::SerializeAsArray() const {
16182   ::protozero::HeapBuffered<::protozero::Message> msg;
16183   Serialize(msg.get());
16184   return msg.SerializeAsArray();
16185 }
16186 
Serialize(::protozero::Message * msg) const16187 void GpuCounterConfig::Serialize(::protozero::Message* msg) const {
16188   // Field 1: counter_period_ns
16189   if (_has_field_[1]) {
16190     msg->AppendVarInt(1, counter_period_ns_);
16191   }
16192 
16193   // Field 2: counter_ids
16194   for (auto& it : counter_ids_) {
16195     msg->AppendVarInt(2, it);
16196   }
16197 
16198   // Field 3: instrumented_sampling
16199   if (_has_field_[3]) {
16200     msg->AppendTinyVarInt(3, instrumented_sampling_);
16201   }
16202 
16203   // Field 4: fix_gpu_clock
16204   if (_has_field_[4]) {
16205     msg->AppendTinyVarInt(4, fix_gpu_clock_);
16206   }
16207 
16208   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
16209 }
16210 
16211 }  // namespace perfetto
16212 }  // namespace protos
16213 }  // namespace gen
16214 #if defined(__GNUC__) || defined(__clang__)
16215 #pragma GCC diagnostic pop
16216 #endif
16217 // gen_amalgamated begin source: gen/protos/perfetto/config/gpu/vulkan_memory_config.gen.cc
16218 // gen_amalgamated begin header: gen/protos/perfetto/config/gpu/vulkan_memory_config.gen.h
16219 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
16220 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_VULKAN_MEMORY_CONFIG_PROTO_CPP_H_
16221 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_VULKAN_MEMORY_CONFIG_PROTO_CPP_H_
16222 
16223 #include <stdint.h>
16224 #include <bitset>
16225 #include <vector>
16226 #include <string>
16227 #include <type_traits>
16228 
16229 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
16230 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
16231 // gen_amalgamated expanded: #include "perfetto/base/export.h"
16232 
16233 namespace perfetto {
16234 namespace protos {
16235 namespace gen {
16236 class VulkanMemoryConfig;
16237 }  // namespace perfetto
16238 }  // namespace protos
16239 }  // namespace gen
16240 
16241 namespace protozero {
16242 class Message;
16243 }  // namespace protozero
16244 
16245 namespace perfetto {
16246 namespace protos {
16247 namespace gen {
16248 
16249 class PERFETTO_EXPORT VulkanMemoryConfig : public ::protozero::CppMessageObj {
16250  public:
16251   enum FieldNumbers {
16252     kTrackDriverMemoryUsageFieldNumber = 1,
16253     kTrackDeviceMemoryUsageFieldNumber = 2,
16254   };
16255 
16256   VulkanMemoryConfig();
16257   ~VulkanMemoryConfig() override;
16258   VulkanMemoryConfig(VulkanMemoryConfig&&) noexcept;
16259   VulkanMemoryConfig& operator=(VulkanMemoryConfig&&);
16260   VulkanMemoryConfig(const VulkanMemoryConfig&);
16261   VulkanMemoryConfig& operator=(const VulkanMemoryConfig&);
16262   bool operator==(const VulkanMemoryConfig&) const;
operator !=(const VulkanMemoryConfig & other) const16263   bool operator!=(const VulkanMemoryConfig& other) const { return !(*this == other); }
16264 
16265   bool ParseFromArray(const void*, size_t) override;
16266   std::string SerializeAsString() const override;
16267   std::vector<uint8_t> SerializeAsArray() const override;
16268   void Serialize(::protozero::Message*) const;
16269 
has_track_driver_memory_usage() const16270   bool has_track_driver_memory_usage() const { return _has_field_[1]; }
track_driver_memory_usage() const16271   bool track_driver_memory_usage() const { return track_driver_memory_usage_; }
set_track_driver_memory_usage(bool value)16272   void set_track_driver_memory_usage(bool value) { track_driver_memory_usage_ = value; _has_field_.set(1); }
16273 
has_track_device_memory_usage() const16274   bool has_track_device_memory_usage() const { return _has_field_[2]; }
track_device_memory_usage() const16275   bool track_device_memory_usage() const { return track_device_memory_usage_; }
set_track_device_memory_usage(bool value)16276   void set_track_device_memory_usage(bool value) { track_device_memory_usage_ = value; _has_field_.set(2); }
16277 
16278  private:
16279   bool track_driver_memory_usage_{};
16280   bool track_device_memory_usage_{};
16281 
16282   // Allows to preserve unknown protobuf fields for compatibility
16283   // with future versions of .proto files.
16284   std::string unknown_fields_;
16285 
16286   std::bitset<3> _has_field_{};
16287 };
16288 
16289 }  // namespace perfetto
16290 }  // namespace protos
16291 }  // namespace gen
16292 
16293 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_VULKAN_MEMORY_CONFIG_PROTO_CPP_H_
16294 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
16295 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
16296 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
16297 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
16298 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
16299 #if defined(__GNUC__) || defined(__clang__)
16300 #pragma GCC diagnostic push
16301 #pragma GCC diagnostic ignored "-Wfloat-equal"
16302 #endif
16303 // gen_amalgamated expanded: #include "protos/perfetto/config/gpu/vulkan_memory_config.gen.h"
16304 
16305 namespace perfetto {
16306 namespace protos {
16307 namespace gen {
16308 
16309 VulkanMemoryConfig::VulkanMemoryConfig() = default;
16310 VulkanMemoryConfig::~VulkanMemoryConfig() = default;
16311 VulkanMemoryConfig::VulkanMemoryConfig(const VulkanMemoryConfig&) = default;
16312 VulkanMemoryConfig& VulkanMemoryConfig::operator=(const VulkanMemoryConfig&) = default;
16313 VulkanMemoryConfig::VulkanMemoryConfig(VulkanMemoryConfig&&) noexcept = default;
16314 VulkanMemoryConfig& VulkanMemoryConfig::operator=(VulkanMemoryConfig&&) = default;
16315 
operator ==(const VulkanMemoryConfig & other) const16316 bool VulkanMemoryConfig::operator==(const VulkanMemoryConfig& other) const {
16317   return unknown_fields_ == other.unknown_fields_
16318    && track_driver_memory_usage_ == other.track_driver_memory_usage_
16319    && track_device_memory_usage_ == other.track_device_memory_usage_;
16320 }
16321 
ParseFromArray(const void * raw,size_t size)16322 bool VulkanMemoryConfig::ParseFromArray(const void* raw, size_t size) {
16323   unknown_fields_.clear();
16324   bool packed_error = false;
16325 
16326   ::protozero::ProtoDecoder dec(raw, size);
16327   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
16328     if (field.id() < _has_field_.size()) {
16329       _has_field_.set(field.id());
16330     }
16331     switch (field.id()) {
16332       case 1 /* track_driver_memory_usage */:
16333         field.get(&track_driver_memory_usage_);
16334         break;
16335       case 2 /* track_device_memory_usage */:
16336         field.get(&track_device_memory_usage_);
16337         break;
16338       default:
16339         field.SerializeAndAppendTo(&unknown_fields_);
16340         break;
16341     }
16342   }
16343   return !packed_error && !dec.bytes_left();
16344 }
16345 
SerializeAsString() const16346 std::string VulkanMemoryConfig::SerializeAsString() const {
16347   ::protozero::HeapBuffered<::protozero::Message> msg;
16348   Serialize(msg.get());
16349   return msg.SerializeAsString();
16350 }
16351 
SerializeAsArray() const16352 std::vector<uint8_t> VulkanMemoryConfig::SerializeAsArray() const {
16353   ::protozero::HeapBuffered<::protozero::Message> msg;
16354   Serialize(msg.get());
16355   return msg.SerializeAsArray();
16356 }
16357 
Serialize(::protozero::Message * msg) const16358 void VulkanMemoryConfig::Serialize(::protozero::Message* msg) const {
16359   // Field 1: track_driver_memory_usage
16360   if (_has_field_[1]) {
16361     msg->AppendTinyVarInt(1, track_driver_memory_usage_);
16362   }
16363 
16364   // Field 2: track_device_memory_usage
16365   if (_has_field_[2]) {
16366     msg->AppendTinyVarInt(2, track_device_memory_usage_);
16367   }
16368 
16369   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
16370 }
16371 
16372 }  // namespace perfetto
16373 }  // namespace protos
16374 }  // namespace gen
16375 #if defined(__GNUC__) || defined(__clang__)
16376 #pragma GCC diagnostic pop
16377 #endif
16378 // gen_amalgamated begin source: gen/protos/perfetto/config/inode_file/inode_file_config.gen.cc
16379 // gen_amalgamated begin header: gen/protos/perfetto/config/inode_file/inode_file_config.gen.h
16380 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
16381 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INODE_FILE_INODE_FILE_CONFIG_PROTO_CPP_H_
16382 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INODE_FILE_INODE_FILE_CONFIG_PROTO_CPP_H_
16383 
16384 #include <stdint.h>
16385 #include <bitset>
16386 #include <vector>
16387 #include <string>
16388 #include <type_traits>
16389 
16390 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
16391 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
16392 // gen_amalgamated expanded: #include "perfetto/base/export.h"
16393 
16394 namespace perfetto {
16395 namespace protos {
16396 namespace gen {
16397 class InodeFileConfig;
16398 class InodeFileConfig_MountPointMappingEntry;
16399 }  // namespace perfetto
16400 }  // namespace protos
16401 }  // namespace gen
16402 
16403 namespace protozero {
16404 class Message;
16405 }  // namespace protozero
16406 
16407 namespace perfetto {
16408 namespace protos {
16409 namespace gen {
16410 
16411 class PERFETTO_EXPORT InodeFileConfig : public ::protozero::CppMessageObj {
16412  public:
16413   using MountPointMappingEntry = InodeFileConfig_MountPointMappingEntry;
16414   enum FieldNumbers {
16415     kScanIntervalMsFieldNumber = 1,
16416     kScanDelayMsFieldNumber = 2,
16417     kScanBatchSizeFieldNumber = 3,
16418     kDoNotScanFieldNumber = 4,
16419     kScanMountPointsFieldNumber = 5,
16420     kMountPointMappingFieldNumber = 6,
16421   };
16422 
16423   InodeFileConfig();
16424   ~InodeFileConfig() override;
16425   InodeFileConfig(InodeFileConfig&&) noexcept;
16426   InodeFileConfig& operator=(InodeFileConfig&&);
16427   InodeFileConfig(const InodeFileConfig&);
16428   InodeFileConfig& operator=(const InodeFileConfig&);
16429   bool operator==(const InodeFileConfig&) const;
operator !=(const InodeFileConfig & other) const16430   bool operator!=(const InodeFileConfig& other) const { return !(*this == other); }
16431 
16432   bool ParseFromArray(const void*, size_t) override;
16433   std::string SerializeAsString() const override;
16434   std::vector<uint8_t> SerializeAsArray() const override;
16435   void Serialize(::protozero::Message*) const;
16436 
has_scan_interval_ms() const16437   bool has_scan_interval_ms() const { return _has_field_[1]; }
scan_interval_ms() const16438   uint32_t scan_interval_ms() const { return scan_interval_ms_; }
set_scan_interval_ms(uint32_t value)16439   void set_scan_interval_ms(uint32_t value) { scan_interval_ms_ = value; _has_field_.set(1); }
16440 
has_scan_delay_ms() const16441   bool has_scan_delay_ms() const { return _has_field_[2]; }
scan_delay_ms() const16442   uint32_t scan_delay_ms() const { return scan_delay_ms_; }
set_scan_delay_ms(uint32_t value)16443   void set_scan_delay_ms(uint32_t value) { scan_delay_ms_ = value; _has_field_.set(2); }
16444 
has_scan_batch_size() const16445   bool has_scan_batch_size() const { return _has_field_[3]; }
scan_batch_size() const16446   uint32_t scan_batch_size() const { return scan_batch_size_; }
set_scan_batch_size(uint32_t value)16447   void set_scan_batch_size(uint32_t value) { scan_batch_size_ = value; _has_field_.set(3); }
16448 
has_do_not_scan() const16449   bool has_do_not_scan() const { return _has_field_[4]; }
do_not_scan() const16450   bool do_not_scan() const { return do_not_scan_; }
set_do_not_scan(bool value)16451   void set_do_not_scan(bool value) { do_not_scan_ = value; _has_field_.set(4); }
16452 
scan_mount_points() const16453   const std::vector<std::string>& scan_mount_points() const { return scan_mount_points_; }
mutable_scan_mount_points()16454   std::vector<std::string>* mutable_scan_mount_points() { return &scan_mount_points_; }
scan_mount_points_size() const16455   int scan_mount_points_size() const { return static_cast<int>(scan_mount_points_.size()); }
clear_scan_mount_points()16456   void clear_scan_mount_points() { scan_mount_points_.clear(); }
add_scan_mount_points(std::string value)16457   void add_scan_mount_points(std::string value) { scan_mount_points_.emplace_back(value); }
add_scan_mount_points()16458   std::string* add_scan_mount_points() { scan_mount_points_.emplace_back(); return &scan_mount_points_.back(); }
16459 
mount_point_mapping() const16460   const std::vector<InodeFileConfig_MountPointMappingEntry>& mount_point_mapping() const { return mount_point_mapping_; }
mutable_mount_point_mapping()16461   std::vector<InodeFileConfig_MountPointMappingEntry>* mutable_mount_point_mapping() { return &mount_point_mapping_; }
16462   int mount_point_mapping_size() const;
16463   void clear_mount_point_mapping();
16464   InodeFileConfig_MountPointMappingEntry* add_mount_point_mapping();
16465 
16466  private:
16467   uint32_t scan_interval_ms_{};
16468   uint32_t scan_delay_ms_{};
16469   uint32_t scan_batch_size_{};
16470   bool do_not_scan_{};
16471   std::vector<std::string> scan_mount_points_;
16472   std::vector<InodeFileConfig_MountPointMappingEntry> mount_point_mapping_;
16473 
16474   // Allows to preserve unknown protobuf fields for compatibility
16475   // with future versions of .proto files.
16476   std::string unknown_fields_;
16477 
16478   std::bitset<7> _has_field_{};
16479 };
16480 
16481 
16482 class PERFETTO_EXPORT InodeFileConfig_MountPointMappingEntry : public ::protozero::CppMessageObj {
16483  public:
16484   enum FieldNumbers {
16485     kMountpointFieldNumber = 1,
16486     kScanRootsFieldNumber = 2,
16487   };
16488 
16489   InodeFileConfig_MountPointMappingEntry();
16490   ~InodeFileConfig_MountPointMappingEntry() override;
16491   InodeFileConfig_MountPointMappingEntry(InodeFileConfig_MountPointMappingEntry&&) noexcept;
16492   InodeFileConfig_MountPointMappingEntry& operator=(InodeFileConfig_MountPointMappingEntry&&);
16493   InodeFileConfig_MountPointMappingEntry(const InodeFileConfig_MountPointMappingEntry&);
16494   InodeFileConfig_MountPointMappingEntry& operator=(const InodeFileConfig_MountPointMappingEntry&);
16495   bool operator==(const InodeFileConfig_MountPointMappingEntry&) const;
operator !=(const InodeFileConfig_MountPointMappingEntry & other) const16496   bool operator!=(const InodeFileConfig_MountPointMappingEntry& other) const { return !(*this == other); }
16497 
16498   bool ParseFromArray(const void*, size_t) override;
16499   std::string SerializeAsString() const override;
16500   std::vector<uint8_t> SerializeAsArray() const override;
16501   void Serialize(::protozero::Message*) const;
16502 
has_mountpoint() const16503   bool has_mountpoint() const { return _has_field_[1]; }
mountpoint() const16504   const std::string& mountpoint() const { return mountpoint_; }
set_mountpoint(const std::string & value)16505   void set_mountpoint(const std::string& value) { mountpoint_ = value; _has_field_.set(1); }
16506 
scan_roots() const16507   const std::vector<std::string>& scan_roots() const { return scan_roots_; }
mutable_scan_roots()16508   std::vector<std::string>* mutable_scan_roots() { return &scan_roots_; }
scan_roots_size() const16509   int scan_roots_size() const { return static_cast<int>(scan_roots_.size()); }
clear_scan_roots()16510   void clear_scan_roots() { scan_roots_.clear(); }
add_scan_roots(std::string value)16511   void add_scan_roots(std::string value) { scan_roots_.emplace_back(value); }
add_scan_roots()16512   std::string* add_scan_roots() { scan_roots_.emplace_back(); return &scan_roots_.back(); }
16513 
16514  private:
16515   std::string mountpoint_{};
16516   std::vector<std::string> scan_roots_;
16517 
16518   // Allows to preserve unknown protobuf fields for compatibility
16519   // with future versions of .proto files.
16520   std::string unknown_fields_;
16521 
16522   std::bitset<3> _has_field_{};
16523 };
16524 
16525 }  // namespace perfetto
16526 }  // namespace protos
16527 }  // namespace gen
16528 
16529 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INODE_FILE_INODE_FILE_CONFIG_PROTO_CPP_H_
16530 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
16531 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
16532 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
16533 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
16534 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
16535 #if defined(__GNUC__) || defined(__clang__)
16536 #pragma GCC diagnostic push
16537 #pragma GCC diagnostic ignored "-Wfloat-equal"
16538 #endif
16539 // gen_amalgamated expanded: #include "protos/perfetto/config/inode_file/inode_file_config.gen.h"
16540 
16541 namespace perfetto {
16542 namespace protos {
16543 namespace gen {
16544 
16545 InodeFileConfig::InodeFileConfig() = default;
16546 InodeFileConfig::~InodeFileConfig() = default;
16547 InodeFileConfig::InodeFileConfig(const InodeFileConfig&) = default;
16548 InodeFileConfig& InodeFileConfig::operator=(const InodeFileConfig&) = default;
16549 InodeFileConfig::InodeFileConfig(InodeFileConfig&&) noexcept = default;
16550 InodeFileConfig& InodeFileConfig::operator=(InodeFileConfig&&) = default;
16551 
operator ==(const InodeFileConfig & other) const16552 bool InodeFileConfig::operator==(const InodeFileConfig& other) const {
16553   return unknown_fields_ == other.unknown_fields_
16554    && scan_interval_ms_ == other.scan_interval_ms_
16555    && scan_delay_ms_ == other.scan_delay_ms_
16556    && scan_batch_size_ == other.scan_batch_size_
16557    && do_not_scan_ == other.do_not_scan_
16558    && scan_mount_points_ == other.scan_mount_points_
16559    && mount_point_mapping_ == other.mount_point_mapping_;
16560 }
16561 
mount_point_mapping_size() const16562 int InodeFileConfig::mount_point_mapping_size() const { return static_cast<int>(mount_point_mapping_.size()); }
clear_mount_point_mapping()16563 void InodeFileConfig::clear_mount_point_mapping() { mount_point_mapping_.clear(); }
add_mount_point_mapping()16564 InodeFileConfig_MountPointMappingEntry* InodeFileConfig::add_mount_point_mapping() { mount_point_mapping_.emplace_back(); return &mount_point_mapping_.back(); }
ParseFromArray(const void * raw,size_t size)16565 bool InodeFileConfig::ParseFromArray(const void* raw, size_t size) {
16566   scan_mount_points_.clear();
16567   mount_point_mapping_.clear();
16568   unknown_fields_.clear();
16569   bool packed_error = false;
16570 
16571   ::protozero::ProtoDecoder dec(raw, size);
16572   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
16573     if (field.id() < _has_field_.size()) {
16574       _has_field_.set(field.id());
16575     }
16576     switch (field.id()) {
16577       case 1 /* scan_interval_ms */:
16578         field.get(&scan_interval_ms_);
16579         break;
16580       case 2 /* scan_delay_ms */:
16581         field.get(&scan_delay_ms_);
16582         break;
16583       case 3 /* scan_batch_size */:
16584         field.get(&scan_batch_size_);
16585         break;
16586       case 4 /* do_not_scan */:
16587         field.get(&do_not_scan_);
16588         break;
16589       case 5 /* scan_mount_points */:
16590         scan_mount_points_.emplace_back();
16591         field.get(&scan_mount_points_.back());
16592         break;
16593       case 6 /* mount_point_mapping */:
16594         mount_point_mapping_.emplace_back();
16595         mount_point_mapping_.back().ParseFromArray(field.data(), field.size());
16596         break;
16597       default:
16598         field.SerializeAndAppendTo(&unknown_fields_);
16599         break;
16600     }
16601   }
16602   return !packed_error && !dec.bytes_left();
16603 }
16604 
SerializeAsString() const16605 std::string InodeFileConfig::SerializeAsString() const {
16606   ::protozero::HeapBuffered<::protozero::Message> msg;
16607   Serialize(msg.get());
16608   return msg.SerializeAsString();
16609 }
16610 
SerializeAsArray() const16611 std::vector<uint8_t> InodeFileConfig::SerializeAsArray() const {
16612   ::protozero::HeapBuffered<::protozero::Message> msg;
16613   Serialize(msg.get());
16614   return msg.SerializeAsArray();
16615 }
16616 
Serialize(::protozero::Message * msg) const16617 void InodeFileConfig::Serialize(::protozero::Message* msg) const {
16618   // Field 1: scan_interval_ms
16619   if (_has_field_[1]) {
16620     msg->AppendVarInt(1, scan_interval_ms_);
16621   }
16622 
16623   // Field 2: scan_delay_ms
16624   if (_has_field_[2]) {
16625     msg->AppendVarInt(2, scan_delay_ms_);
16626   }
16627 
16628   // Field 3: scan_batch_size
16629   if (_has_field_[3]) {
16630     msg->AppendVarInt(3, scan_batch_size_);
16631   }
16632 
16633   // Field 4: do_not_scan
16634   if (_has_field_[4]) {
16635     msg->AppendTinyVarInt(4, do_not_scan_);
16636   }
16637 
16638   // Field 5: scan_mount_points
16639   for (auto& it : scan_mount_points_) {
16640     msg->AppendString(5, it);
16641   }
16642 
16643   // Field 6: mount_point_mapping
16644   for (auto& it : mount_point_mapping_) {
16645     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
16646   }
16647 
16648   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
16649 }
16650 
16651 
16652 InodeFileConfig_MountPointMappingEntry::InodeFileConfig_MountPointMappingEntry() = default;
16653 InodeFileConfig_MountPointMappingEntry::~InodeFileConfig_MountPointMappingEntry() = default;
16654 InodeFileConfig_MountPointMappingEntry::InodeFileConfig_MountPointMappingEntry(const InodeFileConfig_MountPointMappingEntry&) = default;
16655 InodeFileConfig_MountPointMappingEntry& InodeFileConfig_MountPointMappingEntry::operator=(const InodeFileConfig_MountPointMappingEntry&) = default;
16656 InodeFileConfig_MountPointMappingEntry::InodeFileConfig_MountPointMappingEntry(InodeFileConfig_MountPointMappingEntry&&) noexcept = default;
16657 InodeFileConfig_MountPointMappingEntry& InodeFileConfig_MountPointMappingEntry::operator=(InodeFileConfig_MountPointMappingEntry&&) = default;
16658 
operator ==(const InodeFileConfig_MountPointMappingEntry & other) const16659 bool InodeFileConfig_MountPointMappingEntry::operator==(const InodeFileConfig_MountPointMappingEntry& other) const {
16660   return unknown_fields_ == other.unknown_fields_
16661    && mountpoint_ == other.mountpoint_
16662    && scan_roots_ == other.scan_roots_;
16663 }
16664 
ParseFromArray(const void * raw,size_t size)16665 bool InodeFileConfig_MountPointMappingEntry::ParseFromArray(const void* raw, size_t size) {
16666   scan_roots_.clear();
16667   unknown_fields_.clear();
16668   bool packed_error = false;
16669 
16670   ::protozero::ProtoDecoder dec(raw, size);
16671   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
16672     if (field.id() < _has_field_.size()) {
16673       _has_field_.set(field.id());
16674     }
16675     switch (field.id()) {
16676       case 1 /* mountpoint */:
16677         field.get(&mountpoint_);
16678         break;
16679       case 2 /* scan_roots */:
16680         scan_roots_.emplace_back();
16681         field.get(&scan_roots_.back());
16682         break;
16683       default:
16684         field.SerializeAndAppendTo(&unknown_fields_);
16685         break;
16686     }
16687   }
16688   return !packed_error && !dec.bytes_left();
16689 }
16690 
SerializeAsString() const16691 std::string InodeFileConfig_MountPointMappingEntry::SerializeAsString() const {
16692   ::protozero::HeapBuffered<::protozero::Message> msg;
16693   Serialize(msg.get());
16694   return msg.SerializeAsString();
16695 }
16696 
SerializeAsArray() const16697 std::vector<uint8_t> InodeFileConfig_MountPointMappingEntry::SerializeAsArray() const {
16698   ::protozero::HeapBuffered<::protozero::Message> msg;
16699   Serialize(msg.get());
16700   return msg.SerializeAsArray();
16701 }
16702 
Serialize(::protozero::Message * msg) const16703 void InodeFileConfig_MountPointMappingEntry::Serialize(::protozero::Message* msg) const {
16704   // Field 1: mountpoint
16705   if (_has_field_[1]) {
16706     msg->AppendString(1, mountpoint_);
16707   }
16708 
16709   // Field 2: scan_roots
16710   for (auto& it : scan_roots_) {
16711     msg->AppendString(2, it);
16712   }
16713 
16714   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
16715 }
16716 
16717 }  // namespace perfetto
16718 }  // namespace protos
16719 }  // namespace gen
16720 #if defined(__GNUC__) || defined(__clang__)
16721 #pragma GCC diagnostic pop
16722 #endif
16723 // gen_amalgamated begin source: gen/protos/perfetto/config/interceptors/console_config.gen.cc
16724 // gen_amalgamated begin header: gen/protos/perfetto/config/interceptors/console_config.gen.h
16725 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
16726 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTORS_CONSOLE_CONFIG_PROTO_CPP_H_
16727 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTORS_CONSOLE_CONFIG_PROTO_CPP_H_
16728 
16729 #include <stdint.h>
16730 #include <bitset>
16731 #include <vector>
16732 #include <string>
16733 #include <type_traits>
16734 
16735 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
16736 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
16737 // gen_amalgamated expanded: #include "perfetto/base/export.h"
16738 
16739 namespace perfetto {
16740 namespace protos {
16741 namespace gen {
16742 class ConsoleConfig;
16743 enum ConsoleConfig_Output : int;
16744 }  // namespace perfetto
16745 }  // namespace protos
16746 }  // namespace gen
16747 
16748 namespace protozero {
16749 class Message;
16750 }  // namespace protozero
16751 
16752 namespace perfetto {
16753 namespace protos {
16754 namespace gen {
16755 enum ConsoleConfig_Output : int {
16756   ConsoleConfig_Output_OUTPUT_UNSPECIFIED = 0,
16757   ConsoleConfig_Output_OUTPUT_STDOUT = 1,
16758   ConsoleConfig_Output_OUTPUT_STDERR = 2,
16759 };
16760 
16761 class PERFETTO_EXPORT ConsoleConfig : public ::protozero::CppMessageObj {
16762  public:
16763   using Output = ConsoleConfig_Output;
16764   static constexpr auto OUTPUT_UNSPECIFIED = ConsoleConfig_Output_OUTPUT_UNSPECIFIED;
16765   static constexpr auto OUTPUT_STDOUT = ConsoleConfig_Output_OUTPUT_STDOUT;
16766   static constexpr auto OUTPUT_STDERR = ConsoleConfig_Output_OUTPUT_STDERR;
16767   static constexpr auto Output_MIN = ConsoleConfig_Output_OUTPUT_UNSPECIFIED;
16768   static constexpr auto Output_MAX = ConsoleConfig_Output_OUTPUT_STDERR;
16769   enum FieldNumbers {
16770     kOutputFieldNumber = 1,
16771     kEnableColorsFieldNumber = 2,
16772   };
16773 
16774   ConsoleConfig();
16775   ~ConsoleConfig() override;
16776   ConsoleConfig(ConsoleConfig&&) noexcept;
16777   ConsoleConfig& operator=(ConsoleConfig&&);
16778   ConsoleConfig(const ConsoleConfig&);
16779   ConsoleConfig& operator=(const ConsoleConfig&);
16780   bool operator==(const ConsoleConfig&) const;
operator !=(const ConsoleConfig & other) const16781   bool operator!=(const ConsoleConfig& other) const { return !(*this == other); }
16782 
16783   bool ParseFromArray(const void*, size_t) override;
16784   std::string SerializeAsString() const override;
16785   std::vector<uint8_t> SerializeAsArray() const override;
16786   void Serialize(::protozero::Message*) const;
16787 
has_output() const16788   bool has_output() const { return _has_field_[1]; }
output() const16789   ConsoleConfig_Output output() const { return output_; }
set_output(ConsoleConfig_Output value)16790   void set_output(ConsoleConfig_Output value) { output_ = value; _has_field_.set(1); }
16791 
has_enable_colors() const16792   bool has_enable_colors() const { return _has_field_[2]; }
enable_colors() const16793   bool enable_colors() const { return enable_colors_; }
set_enable_colors(bool value)16794   void set_enable_colors(bool value) { enable_colors_ = value; _has_field_.set(2); }
16795 
16796  private:
16797   ConsoleConfig_Output output_{};
16798   bool enable_colors_{};
16799 
16800   // Allows to preserve unknown protobuf fields for compatibility
16801   // with future versions of .proto files.
16802   std::string unknown_fields_;
16803 
16804   std::bitset<3> _has_field_{};
16805 };
16806 
16807 }  // namespace perfetto
16808 }  // namespace protos
16809 }  // namespace gen
16810 
16811 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTORS_CONSOLE_CONFIG_PROTO_CPP_H_
16812 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
16813 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
16814 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
16815 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
16816 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
16817 #if defined(__GNUC__) || defined(__clang__)
16818 #pragma GCC diagnostic push
16819 #pragma GCC diagnostic ignored "-Wfloat-equal"
16820 #endif
16821 // gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
16822 
16823 namespace perfetto {
16824 namespace protos {
16825 namespace gen {
16826 
16827 ConsoleConfig::ConsoleConfig() = default;
16828 ConsoleConfig::~ConsoleConfig() = default;
16829 ConsoleConfig::ConsoleConfig(const ConsoleConfig&) = default;
16830 ConsoleConfig& ConsoleConfig::operator=(const ConsoleConfig&) = default;
16831 ConsoleConfig::ConsoleConfig(ConsoleConfig&&) noexcept = default;
16832 ConsoleConfig& ConsoleConfig::operator=(ConsoleConfig&&) = default;
16833 
operator ==(const ConsoleConfig & other) const16834 bool ConsoleConfig::operator==(const ConsoleConfig& other) const {
16835   return unknown_fields_ == other.unknown_fields_
16836    && output_ == other.output_
16837    && enable_colors_ == other.enable_colors_;
16838 }
16839 
ParseFromArray(const void * raw,size_t size)16840 bool ConsoleConfig::ParseFromArray(const void* raw, size_t size) {
16841   unknown_fields_.clear();
16842   bool packed_error = false;
16843 
16844   ::protozero::ProtoDecoder dec(raw, size);
16845   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
16846     if (field.id() < _has_field_.size()) {
16847       _has_field_.set(field.id());
16848     }
16849     switch (field.id()) {
16850       case 1 /* output */:
16851         field.get(&output_);
16852         break;
16853       case 2 /* enable_colors */:
16854         field.get(&enable_colors_);
16855         break;
16856       default:
16857         field.SerializeAndAppendTo(&unknown_fields_);
16858         break;
16859     }
16860   }
16861   return !packed_error && !dec.bytes_left();
16862 }
16863 
SerializeAsString() const16864 std::string ConsoleConfig::SerializeAsString() const {
16865   ::protozero::HeapBuffered<::protozero::Message> msg;
16866   Serialize(msg.get());
16867   return msg.SerializeAsString();
16868 }
16869 
SerializeAsArray() const16870 std::vector<uint8_t> ConsoleConfig::SerializeAsArray() const {
16871   ::protozero::HeapBuffered<::protozero::Message> msg;
16872   Serialize(msg.get());
16873   return msg.SerializeAsArray();
16874 }
16875 
Serialize(::protozero::Message * msg) const16876 void ConsoleConfig::Serialize(::protozero::Message* msg) const {
16877   // Field 1: output
16878   if (_has_field_[1]) {
16879     msg->AppendVarInt(1, output_);
16880   }
16881 
16882   // Field 2: enable_colors
16883   if (_has_field_[2]) {
16884     msg->AppendTinyVarInt(2, enable_colors_);
16885   }
16886 
16887   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
16888 }
16889 
16890 }  // namespace perfetto
16891 }  // namespace protos
16892 }  // namespace gen
16893 #if defined(__GNUC__) || defined(__clang__)
16894 #pragma GCC diagnostic pop
16895 #endif
16896 // gen_amalgamated begin source: gen/protos/perfetto/config/power/android_power_config.gen.cc
16897 // gen_amalgamated begin header: gen/protos/perfetto/config/power/android_power_config.gen.h
16898 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
16899 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_POWER_ANDROID_POWER_CONFIG_PROTO_CPP_H_
16900 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_POWER_ANDROID_POWER_CONFIG_PROTO_CPP_H_
16901 
16902 #include <stdint.h>
16903 #include <bitset>
16904 #include <vector>
16905 #include <string>
16906 #include <type_traits>
16907 
16908 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
16909 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
16910 // gen_amalgamated expanded: #include "perfetto/base/export.h"
16911 
16912 namespace perfetto {
16913 namespace protos {
16914 namespace gen {
16915 class AndroidPowerConfig;
16916 enum AndroidPowerConfig_BatteryCounters : int;
16917 }  // namespace perfetto
16918 }  // namespace protos
16919 }  // namespace gen
16920 
16921 namespace protozero {
16922 class Message;
16923 }  // namespace protozero
16924 
16925 namespace perfetto {
16926 namespace protos {
16927 namespace gen {
16928 enum AndroidPowerConfig_BatteryCounters : int {
16929   AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_UNSPECIFIED = 0,
16930   AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CHARGE = 1,
16931   AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CAPACITY_PERCENT = 2,
16932   AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CURRENT = 3,
16933   AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CURRENT_AVG = 4,
16934 };
16935 
16936 class PERFETTO_EXPORT AndroidPowerConfig : public ::protozero::CppMessageObj {
16937  public:
16938   using BatteryCounters = AndroidPowerConfig_BatteryCounters;
16939   static constexpr auto BATTERY_COUNTER_UNSPECIFIED = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_UNSPECIFIED;
16940   static constexpr auto BATTERY_COUNTER_CHARGE = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CHARGE;
16941   static constexpr auto BATTERY_COUNTER_CAPACITY_PERCENT = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CAPACITY_PERCENT;
16942   static constexpr auto BATTERY_COUNTER_CURRENT = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CURRENT;
16943   static constexpr auto BATTERY_COUNTER_CURRENT_AVG = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CURRENT_AVG;
16944   static constexpr auto BatteryCounters_MIN = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_UNSPECIFIED;
16945   static constexpr auto BatteryCounters_MAX = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CURRENT_AVG;
16946   enum FieldNumbers {
16947     kBatteryPollMsFieldNumber = 1,
16948     kBatteryCountersFieldNumber = 2,
16949     kCollectPowerRailsFieldNumber = 3,
16950     kCollectEnergyEstimationBreakdownFieldNumber = 4,
16951   };
16952 
16953   AndroidPowerConfig();
16954   ~AndroidPowerConfig() override;
16955   AndroidPowerConfig(AndroidPowerConfig&&) noexcept;
16956   AndroidPowerConfig& operator=(AndroidPowerConfig&&);
16957   AndroidPowerConfig(const AndroidPowerConfig&);
16958   AndroidPowerConfig& operator=(const AndroidPowerConfig&);
16959   bool operator==(const AndroidPowerConfig&) const;
operator !=(const AndroidPowerConfig & other) const16960   bool operator!=(const AndroidPowerConfig& other) const { return !(*this == other); }
16961 
16962   bool ParseFromArray(const void*, size_t) override;
16963   std::string SerializeAsString() const override;
16964   std::vector<uint8_t> SerializeAsArray() const override;
16965   void Serialize(::protozero::Message*) const;
16966 
has_battery_poll_ms() const16967   bool has_battery_poll_ms() const { return _has_field_[1]; }
battery_poll_ms() const16968   uint32_t battery_poll_ms() const { return battery_poll_ms_; }
set_battery_poll_ms(uint32_t value)16969   void set_battery_poll_ms(uint32_t value) { battery_poll_ms_ = value; _has_field_.set(1); }
16970 
battery_counters() const16971   const std::vector<AndroidPowerConfig_BatteryCounters>& battery_counters() const { return battery_counters_; }
mutable_battery_counters()16972   std::vector<AndroidPowerConfig_BatteryCounters>* mutable_battery_counters() { return &battery_counters_; }
battery_counters_size() const16973   int battery_counters_size() const { return static_cast<int>(battery_counters_.size()); }
clear_battery_counters()16974   void clear_battery_counters() { battery_counters_.clear(); }
add_battery_counters(AndroidPowerConfig_BatteryCounters value)16975   void add_battery_counters(AndroidPowerConfig_BatteryCounters value) { battery_counters_.emplace_back(value); }
add_battery_counters()16976   AndroidPowerConfig_BatteryCounters* add_battery_counters() { battery_counters_.emplace_back(); return &battery_counters_.back(); }
16977 
has_collect_power_rails() const16978   bool has_collect_power_rails() const { return _has_field_[3]; }
collect_power_rails() const16979   bool collect_power_rails() const { return collect_power_rails_; }
set_collect_power_rails(bool value)16980   void set_collect_power_rails(bool value) { collect_power_rails_ = value; _has_field_.set(3); }
16981 
has_collect_energy_estimation_breakdown() const16982   bool has_collect_energy_estimation_breakdown() const { return _has_field_[4]; }
collect_energy_estimation_breakdown() const16983   bool collect_energy_estimation_breakdown() const { return collect_energy_estimation_breakdown_; }
set_collect_energy_estimation_breakdown(bool value)16984   void set_collect_energy_estimation_breakdown(bool value) { collect_energy_estimation_breakdown_ = value; _has_field_.set(4); }
16985 
16986  private:
16987   uint32_t battery_poll_ms_{};
16988   std::vector<AndroidPowerConfig_BatteryCounters> battery_counters_;
16989   bool collect_power_rails_{};
16990   bool collect_energy_estimation_breakdown_{};
16991 
16992   // Allows to preserve unknown protobuf fields for compatibility
16993   // with future versions of .proto files.
16994   std::string unknown_fields_;
16995 
16996   std::bitset<5> _has_field_{};
16997 };
16998 
16999 }  // namespace perfetto
17000 }  // namespace protos
17001 }  // namespace gen
17002 
17003 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_POWER_ANDROID_POWER_CONFIG_PROTO_CPP_H_
17004 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
17005 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
17006 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
17007 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
17008 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
17009 #if defined(__GNUC__) || defined(__clang__)
17010 #pragma GCC diagnostic push
17011 #pragma GCC diagnostic ignored "-Wfloat-equal"
17012 #endif
17013 // gen_amalgamated expanded: #include "protos/perfetto/config/power/android_power_config.gen.h"
17014 
17015 namespace perfetto {
17016 namespace protos {
17017 namespace gen {
17018 
17019 AndroidPowerConfig::AndroidPowerConfig() = default;
17020 AndroidPowerConfig::~AndroidPowerConfig() = default;
17021 AndroidPowerConfig::AndroidPowerConfig(const AndroidPowerConfig&) = default;
17022 AndroidPowerConfig& AndroidPowerConfig::operator=(const AndroidPowerConfig&) = default;
17023 AndroidPowerConfig::AndroidPowerConfig(AndroidPowerConfig&&) noexcept = default;
17024 AndroidPowerConfig& AndroidPowerConfig::operator=(AndroidPowerConfig&&) = default;
17025 
operator ==(const AndroidPowerConfig & other) const17026 bool AndroidPowerConfig::operator==(const AndroidPowerConfig& other) const {
17027   return unknown_fields_ == other.unknown_fields_
17028    && battery_poll_ms_ == other.battery_poll_ms_
17029    && battery_counters_ == other.battery_counters_
17030    && collect_power_rails_ == other.collect_power_rails_
17031    && collect_energy_estimation_breakdown_ == other.collect_energy_estimation_breakdown_;
17032 }
17033 
ParseFromArray(const void * raw,size_t size)17034 bool AndroidPowerConfig::ParseFromArray(const void* raw, size_t size) {
17035   battery_counters_.clear();
17036   unknown_fields_.clear();
17037   bool packed_error = false;
17038 
17039   ::protozero::ProtoDecoder dec(raw, size);
17040   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
17041     if (field.id() < _has_field_.size()) {
17042       _has_field_.set(field.id());
17043     }
17044     switch (field.id()) {
17045       case 1 /* battery_poll_ms */:
17046         field.get(&battery_poll_ms_);
17047         break;
17048       case 2 /* battery_counters */:
17049         battery_counters_.emplace_back();
17050         field.get(&battery_counters_.back());
17051         break;
17052       case 3 /* collect_power_rails */:
17053         field.get(&collect_power_rails_);
17054         break;
17055       case 4 /* collect_energy_estimation_breakdown */:
17056         field.get(&collect_energy_estimation_breakdown_);
17057         break;
17058       default:
17059         field.SerializeAndAppendTo(&unknown_fields_);
17060         break;
17061     }
17062   }
17063   return !packed_error && !dec.bytes_left();
17064 }
17065 
SerializeAsString() const17066 std::string AndroidPowerConfig::SerializeAsString() const {
17067   ::protozero::HeapBuffered<::protozero::Message> msg;
17068   Serialize(msg.get());
17069   return msg.SerializeAsString();
17070 }
17071 
SerializeAsArray() const17072 std::vector<uint8_t> AndroidPowerConfig::SerializeAsArray() const {
17073   ::protozero::HeapBuffered<::protozero::Message> msg;
17074   Serialize(msg.get());
17075   return msg.SerializeAsArray();
17076 }
17077 
Serialize(::protozero::Message * msg) const17078 void AndroidPowerConfig::Serialize(::protozero::Message* msg) const {
17079   // Field 1: battery_poll_ms
17080   if (_has_field_[1]) {
17081     msg->AppendVarInt(1, battery_poll_ms_);
17082   }
17083 
17084   // Field 2: battery_counters
17085   for (auto& it : battery_counters_) {
17086     msg->AppendVarInt(2, it);
17087   }
17088 
17089   // Field 3: collect_power_rails
17090   if (_has_field_[3]) {
17091     msg->AppendTinyVarInt(3, collect_power_rails_);
17092   }
17093 
17094   // Field 4: collect_energy_estimation_breakdown
17095   if (_has_field_[4]) {
17096     msg->AppendTinyVarInt(4, collect_energy_estimation_breakdown_);
17097   }
17098 
17099   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
17100 }
17101 
17102 }  // namespace perfetto
17103 }  // namespace protos
17104 }  // namespace gen
17105 #if defined(__GNUC__) || defined(__clang__)
17106 #pragma GCC diagnostic pop
17107 #endif
17108 // gen_amalgamated begin source: gen/protos/perfetto/config/process_stats/process_stats_config.gen.cc
17109 // gen_amalgamated begin header: gen/protos/perfetto/config/process_stats/process_stats_config.gen.h
17110 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
17111 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROCESS_STATS_PROCESS_STATS_CONFIG_PROTO_CPP_H_
17112 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROCESS_STATS_PROCESS_STATS_CONFIG_PROTO_CPP_H_
17113 
17114 #include <stdint.h>
17115 #include <bitset>
17116 #include <vector>
17117 #include <string>
17118 #include <type_traits>
17119 
17120 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
17121 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
17122 // gen_amalgamated expanded: #include "perfetto/base/export.h"
17123 
17124 namespace perfetto {
17125 namespace protos {
17126 namespace gen {
17127 class ProcessStatsConfig;
17128 enum ProcessStatsConfig_Quirks : int;
17129 }  // namespace perfetto
17130 }  // namespace protos
17131 }  // namespace gen
17132 
17133 namespace protozero {
17134 class Message;
17135 }  // namespace protozero
17136 
17137 namespace perfetto {
17138 namespace protos {
17139 namespace gen {
17140 enum ProcessStatsConfig_Quirks : int {
17141   ProcessStatsConfig_Quirks_QUIRKS_UNSPECIFIED = 0,
17142   ProcessStatsConfig_Quirks_DISABLE_INITIAL_DUMP = 1,
17143   ProcessStatsConfig_Quirks_DISABLE_ON_DEMAND = 2,
17144 };
17145 
17146 class PERFETTO_EXPORT ProcessStatsConfig : public ::protozero::CppMessageObj {
17147  public:
17148   using Quirks = ProcessStatsConfig_Quirks;
17149   static constexpr auto QUIRKS_UNSPECIFIED = ProcessStatsConfig_Quirks_QUIRKS_UNSPECIFIED;
17150   static constexpr auto DISABLE_INITIAL_DUMP = ProcessStatsConfig_Quirks_DISABLE_INITIAL_DUMP;
17151   static constexpr auto DISABLE_ON_DEMAND = ProcessStatsConfig_Quirks_DISABLE_ON_DEMAND;
17152   static constexpr auto Quirks_MIN = ProcessStatsConfig_Quirks_QUIRKS_UNSPECIFIED;
17153   static constexpr auto Quirks_MAX = ProcessStatsConfig_Quirks_DISABLE_ON_DEMAND;
17154   enum FieldNumbers {
17155     kQuirksFieldNumber = 1,
17156     kScanAllProcessesOnStartFieldNumber = 2,
17157     kRecordThreadNamesFieldNumber = 3,
17158     kProcStatsPollMsFieldNumber = 4,
17159     kProcStatsCacheTtlMsFieldNumber = 6,
17160     kRecordThreadTimeInStateFieldNumber = 7,
17161     kThreadTimeInStateCacheSizeFieldNumber = 8,
17162   };
17163 
17164   ProcessStatsConfig();
17165   ~ProcessStatsConfig() override;
17166   ProcessStatsConfig(ProcessStatsConfig&&) noexcept;
17167   ProcessStatsConfig& operator=(ProcessStatsConfig&&);
17168   ProcessStatsConfig(const ProcessStatsConfig&);
17169   ProcessStatsConfig& operator=(const ProcessStatsConfig&);
17170   bool operator==(const ProcessStatsConfig&) const;
operator !=(const ProcessStatsConfig & other) const17171   bool operator!=(const ProcessStatsConfig& other) const { return !(*this == other); }
17172 
17173   bool ParseFromArray(const void*, size_t) override;
17174   std::string SerializeAsString() const override;
17175   std::vector<uint8_t> SerializeAsArray() const override;
17176   void Serialize(::protozero::Message*) const;
17177 
quirks() const17178   const std::vector<ProcessStatsConfig_Quirks>& quirks() const { return quirks_; }
mutable_quirks()17179   std::vector<ProcessStatsConfig_Quirks>* mutable_quirks() { return &quirks_; }
quirks_size() const17180   int quirks_size() const { return static_cast<int>(quirks_.size()); }
clear_quirks()17181   void clear_quirks() { quirks_.clear(); }
add_quirks(ProcessStatsConfig_Quirks value)17182   void add_quirks(ProcessStatsConfig_Quirks value) { quirks_.emplace_back(value); }
add_quirks()17183   ProcessStatsConfig_Quirks* add_quirks() { quirks_.emplace_back(); return &quirks_.back(); }
17184 
has_scan_all_processes_on_start() const17185   bool has_scan_all_processes_on_start() const { return _has_field_[2]; }
scan_all_processes_on_start() const17186   bool scan_all_processes_on_start() const { return scan_all_processes_on_start_; }
set_scan_all_processes_on_start(bool value)17187   void set_scan_all_processes_on_start(bool value) { scan_all_processes_on_start_ = value; _has_field_.set(2); }
17188 
has_record_thread_names() const17189   bool has_record_thread_names() const { return _has_field_[3]; }
record_thread_names() const17190   bool record_thread_names() const { return record_thread_names_; }
set_record_thread_names(bool value)17191   void set_record_thread_names(bool value) { record_thread_names_ = value; _has_field_.set(3); }
17192 
has_proc_stats_poll_ms() const17193   bool has_proc_stats_poll_ms() const { return _has_field_[4]; }
proc_stats_poll_ms() const17194   uint32_t proc_stats_poll_ms() const { return proc_stats_poll_ms_; }
set_proc_stats_poll_ms(uint32_t value)17195   void set_proc_stats_poll_ms(uint32_t value) { proc_stats_poll_ms_ = value; _has_field_.set(4); }
17196 
has_proc_stats_cache_ttl_ms() const17197   bool has_proc_stats_cache_ttl_ms() const { return _has_field_[6]; }
proc_stats_cache_ttl_ms() const17198   uint32_t proc_stats_cache_ttl_ms() const { return proc_stats_cache_ttl_ms_; }
set_proc_stats_cache_ttl_ms(uint32_t value)17199   void set_proc_stats_cache_ttl_ms(uint32_t value) { proc_stats_cache_ttl_ms_ = value; _has_field_.set(6); }
17200 
has_record_thread_time_in_state() const17201   bool has_record_thread_time_in_state() const { return _has_field_[7]; }
record_thread_time_in_state() const17202   bool record_thread_time_in_state() const { return record_thread_time_in_state_; }
set_record_thread_time_in_state(bool value)17203   void set_record_thread_time_in_state(bool value) { record_thread_time_in_state_ = value; _has_field_.set(7); }
17204 
has_thread_time_in_state_cache_size() const17205   bool has_thread_time_in_state_cache_size() const { return _has_field_[8]; }
thread_time_in_state_cache_size() const17206   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)17207   void set_thread_time_in_state_cache_size(uint32_t value) { thread_time_in_state_cache_size_ = value; _has_field_.set(8); }
17208 
17209  private:
17210   std::vector<ProcessStatsConfig_Quirks> quirks_;
17211   bool scan_all_processes_on_start_{};
17212   bool record_thread_names_{};
17213   uint32_t proc_stats_poll_ms_{};
17214   uint32_t proc_stats_cache_ttl_ms_{};
17215   bool record_thread_time_in_state_{};
17216   uint32_t thread_time_in_state_cache_size_{};
17217 
17218   // Allows to preserve unknown protobuf fields for compatibility
17219   // with future versions of .proto files.
17220   std::string unknown_fields_;
17221 
17222   std::bitset<9> _has_field_{};
17223 };
17224 
17225 }  // namespace perfetto
17226 }  // namespace protos
17227 }  // namespace gen
17228 
17229 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROCESS_STATS_PROCESS_STATS_CONFIG_PROTO_CPP_H_
17230 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
17231 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
17232 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
17233 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
17234 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
17235 #if defined(__GNUC__) || defined(__clang__)
17236 #pragma GCC diagnostic push
17237 #pragma GCC diagnostic ignored "-Wfloat-equal"
17238 #endif
17239 // gen_amalgamated expanded: #include "protos/perfetto/config/process_stats/process_stats_config.gen.h"
17240 
17241 namespace perfetto {
17242 namespace protos {
17243 namespace gen {
17244 
17245 ProcessStatsConfig::ProcessStatsConfig() = default;
17246 ProcessStatsConfig::~ProcessStatsConfig() = default;
17247 ProcessStatsConfig::ProcessStatsConfig(const ProcessStatsConfig&) = default;
17248 ProcessStatsConfig& ProcessStatsConfig::operator=(const ProcessStatsConfig&) = default;
17249 ProcessStatsConfig::ProcessStatsConfig(ProcessStatsConfig&&) noexcept = default;
17250 ProcessStatsConfig& ProcessStatsConfig::operator=(ProcessStatsConfig&&) = default;
17251 
operator ==(const ProcessStatsConfig & other) const17252 bool ProcessStatsConfig::operator==(const ProcessStatsConfig& other) const {
17253   return unknown_fields_ == other.unknown_fields_
17254    && quirks_ == other.quirks_
17255    && scan_all_processes_on_start_ == other.scan_all_processes_on_start_
17256    && record_thread_names_ == other.record_thread_names_
17257    && proc_stats_poll_ms_ == other.proc_stats_poll_ms_
17258    && proc_stats_cache_ttl_ms_ == other.proc_stats_cache_ttl_ms_
17259    && record_thread_time_in_state_ == other.record_thread_time_in_state_
17260    && thread_time_in_state_cache_size_ == other.thread_time_in_state_cache_size_;
17261 }
17262 
ParseFromArray(const void * raw,size_t size)17263 bool ProcessStatsConfig::ParseFromArray(const void* raw, size_t size) {
17264   quirks_.clear();
17265   unknown_fields_.clear();
17266   bool packed_error = false;
17267 
17268   ::protozero::ProtoDecoder dec(raw, size);
17269   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
17270     if (field.id() < _has_field_.size()) {
17271       _has_field_.set(field.id());
17272     }
17273     switch (field.id()) {
17274       case 1 /* quirks */:
17275         quirks_.emplace_back();
17276         field.get(&quirks_.back());
17277         break;
17278       case 2 /* scan_all_processes_on_start */:
17279         field.get(&scan_all_processes_on_start_);
17280         break;
17281       case 3 /* record_thread_names */:
17282         field.get(&record_thread_names_);
17283         break;
17284       case 4 /* proc_stats_poll_ms */:
17285         field.get(&proc_stats_poll_ms_);
17286         break;
17287       case 6 /* proc_stats_cache_ttl_ms */:
17288         field.get(&proc_stats_cache_ttl_ms_);
17289         break;
17290       case 7 /* record_thread_time_in_state */:
17291         field.get(&record_thread_time_in_state_);
17292         break;
17293       case 8 /* thread_time_in_state_cache_size */:
17294         field.get(&thread_time_in_state_cache_size_);
17295         break;
17296       default:
17297         field.SerializeAndAppendTo(&unknown_fields_);
17298         break;
17299     }
17300   }
17301   return !packed_error && !dec.bytes_left();
17302 }
17303 
SerializeAsString() const17304 std::string ProcessStatsConfig::SerializeAsString() const {
17305   ::protozero::HeapBuffered<::protozero::Message> msg;
17306   Serialize(msg.get());
17307   return msg.SerializeAsString();
17308 }
17309 
SerializeAsArray() const17310 std::vector<uint8_t> ProcessStatsConfig::SerializeAsArray() const {
17311   ::protozero::HeapBuffered<::protozero::Message> msg;
17312   Serialize(msg.get());
17313   return msg.SerializeAsArray();
17314 }
17315 
Serialize(::protozero::Message * msg) const17316 void ProcessStatsConfig::Serialize(::protozero::Message* msg) const {
17317   // Field 1: quirks
17318   for (auto& it : quirks_) {
17319     msg->AppendVarInt(1, it);
17320   }
17321 
17322   // Field 2: scan_all_processes_on_start
17323   if (_has_field_[2]) {
17324     msg->AppendTinyVarInt(2, scan_all_processes_on_start_);
17325   }
17326 
17327   // Field 3: record_thread_names
17328   if (_has_field_[3]) {
17329     msg->AppendTinyVarInt(3, record_thread_names_);
17330   }
17331 
17332   // Field 4: proc_stats_poll_ms
17333   if (_has_field_[4]) {
17334     msg->AppendVarInt(4, proc_stats_poll_ms_);
17335   }
17336 
17337   // Field 6: proc_stats_cache_ttl_ms
17338   if (_has_field_[6]) {
17339     msg->AppendVarInt(6, proc_stats_cache_ttl_ms_);
17340   }
17341 
17342   // Field 7: record_thread_time_in_state
17343   if (_has_field_[7]) {
17344     msg->AppendTinyVarInt(7, record_thread_time_in_state_);
17345   }
17346 
17347   // Field 8: thread_time_in_state_cache_size
17348   if (_has_field_[8]) {
17349     msg->AppendVarInt(8, thread_time_in_state_cache_size_);
17350   }
17351 
17352   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
17353 }
17354 
17355 }  // namespace perfetto
17356 }  // namespace protos
17357 }  // namespace gen
17358 #if defined(__GNUC__) || defined(__clang__)
17359 #pragma GCC diagnostic pop
17360 #endif
17361 // gen_amalgamated begin source: gen/protos/perfetto/config/profiling/heapprofd_config.gen.cc
17362 // gen_amalgamated begin header: gen/protos/perfetto/config/profiling/heapprofd_config.gen.h
17363 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
17364 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_HEAPPROFD_CONFIG_PROTO_CPP_H_
17365 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_HEAPPROFD_CONFIG_PROTO_CPP_H_
17366 
17367 #include <stdint.h>
17368 #include <bitset>
17369 #include <vector>
17370 #include <string>
17371 #include <type_traits>
17372 
17373 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
17374 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
17375 // gen_amalgamated expanded: #include "perfetto/base/export.h"
17376 
17377 namespace perfetto {
17378 namespace protos {
17379 namespace gen {
17380 class HeapprofdConfig;
17381 class HeapprofdConfig_ContinuousDumpConfig;
17382 }  // namespace perfetto
17383 }  // namespace protos
17384 }  // namespace gen
17385 
17386 namespace protozero {
17387 class Message;
17388 }  // namespace protozero
17389 
17390 namespace perfetto {
17391 namespace protos {
17392 namespace gen {
17393 
17394 class PERFETTO_EXPORT HeapprofdConfig : public ::protozero::CppMessageObj {
17395  public:
17396   using ContinuousDumpConfig = HeapprofdConfig_ContinuousDumpConfig;
17397   enum FieldNumbers {
17398     kSamplingIntervalBytesFieldNumber = 1,
17399     kAdaptiveSamplingShmemThresholdFieldNumber = 24,
17400     kAdaptiveSamplingMaxSamplingIntervalBytesFieldNumber = 25,
17401     kProcessCmdlineFieldNumber = 2,
17402     kPidFieldNumber = 4,
17403     kTargetInstalledByFieldNumber = 26,
17404     kHeapsFieldNumber = 20,
17405     kExcludeHeapsFieldNumber = 27,
17406     kStreamAllocationsFieldNumber = 23,
17407     kHeapSamplingIntervalsFieldNumber = 22,
17408     kAllHeapsFieldNumber = 21,
17409     kAllFieldNumber = 5,
17410     kMinAnonymousMemoryKbFieldNumber = 15,
17411     kMaxHeapprofdMemoryKbFieldNumber = 16,
17412     kMaxHeapprofdCpuSecsFieldNumber = 17,
17413     kSkipSymbolPrefixFieldNumber = 7,
17414     kContinuousDumpConfigFieldNumber = 6,
17415     kShmemSizeBytesFieldNumber = 8,
17416     kBlockClientFieldNumber = 9,
17417     kBlockClientTimeoutUsFieldNumber = 14,
17418     kNoStartupFieldNumber = 10,
17419     kNoRunningFieldNumber = 11,
17420     kDumpAtMaxFieldNumber = 13,
17421     kDisableForkTeardownFieldNumber = 18,
17422     kDisableVforkDetectionFieldNumber = 19,
17423   };
17424 
17425   HeapprofdConfig();
17426   ~HeapprofdConfig() override;
17427   HeapprofdConfig(HeapprofdConfig&&) noexcept;
17428   HeapprofdConfig& operator=(HeapprofdConfig&&);
17429   HeapprofdConfig(const HeapprofdConfig&);
17430   HeapprofdConfig& operator=(const HeapprofdConfig&);
17431   bool operator==(const HeapprofdConfig&) const;
operator !=(const HeapprofdConfig & other) const17432   bool operator!=(const HeapprofdConfig& other) const { return !(*this == other); }
17433 
17434   bool ParseFromArray(const void*, size_t) override;
17435   std::string SerializeAsString() const override;
17436   std::vector<uint8_t> SerializeAsArray() const override;
17437   void Serialize(::protozero::Message*) const;
17438 
has_sampling_interval_bytes() const17439   bool has_sampling_interval_bytes() const { return _has_field_[1]; }
sampling_interval_bytes() const17440   uint64_t sampling_interval_bytes() const { return sampling_interval_bytes_; }
set_sampling_interval_bytes(uint64_t value)17441   void set_sampling_interval_bytes(uint64_t value) { sampling_interval_bytes_ = value; _has_field_.set(1); }
17442 
has_adaptive_sampling_shmem_threshold() const17443   bool has_adaptive_sampling_shmem_threshold() const { return _has_field_[24]; }
adaptive_sampling_shmem_threshold() const17444   uint64_t adaptive_sampling_shmem_threshold() const { return adaptive_sampling_shmem_threshold_; }
set_adaptive_sampling_shmem_threshold(uint64_t value)17445   void set_adaptive_sampling_shmem_threshold(uint64_t value) { adaptive_sampling_shmem_threshold_ = value; _has_field_.set(24); }
17446 
has_adaptive_sampling_max_sampling_interval_bytes() const17447   bool has_adaptive_sampling_max_sampling_interval_bytes() const { return _has_field_[25]; }
adaptive_sampling_max_sampling_interval_bytes() const17448   uint64_t adaptive_sampling_max_sampling_interval_bytes() const { return adaptive_sampling_max_sampling_interval_bytes_; }
set_adaptive_sampling_max_sampling_interval_bytes(uint64_t value)17449   void set_adaptive_sampling_max_sampling_interval_bytes(uint64_t value) { adaptive_sampling_max_sampling_interval_bytes_ = value; _has_field_.set(25); }
17450 
process_cmdline() const17451   const std::vector<std::string>& process_cmdline() const { return process_cmdline_; }
mutable_process_cmdline()17452   std::vector<std::string>* mutable_process_cmdline() { return &process_cmdline_; }
process_cmdline_size() const17453   int process_cmdline_size() const { return static_cast<int>(process_cmdline_.size()); }
clear_process_cmdline()17454   void clear_process_cmdline() { process_cmdline_.clear(); }
add_process_cmdline(std::string value)17455   void add_process_cmdline(std::string value) { process_cmdline_.emplace_back(value); }
add_process_cmdline()17456   std::string* add_process_cmdline() { process_cmdline_.emplace_back(); return &process_cmdline_.back(); }
17457 
pid() const17458   const std::vector<uint64_t>& pid() const { return pid_; }
mutable_pid()17459   std::vector<uint64_t>* mutable_pid() { return &pid_; }
pid_size() const17460   int pid_size() const { return static_cast<int>(pid_.size()); }
clear_pid()17461   void clear_pid() { pid_.clear(); }
add_pid(uint64_t value)17462   void add_pid(uint64_t value) { pid_.emplace_back(value); }
add_pid()17463   uint64_t* add_pid() { pid_.emplace_back(); return &pid_.back(); }
17464 
target_installed_by() const17465   const std::vector<std::string>& target_installed_by() const { return target_installed_by_; }
mutable_target_installed_by()17466   std::vector<std::string>* mutable_target_installed_by() { return &target_installed_by_; }
target_installed_by_size() const17467   int target_installed_by_size() const { return static_cast<int>(target_installed_by_.size()); }
clear_target_installed_by()17468   void clear_target_installed_by() { target_installed_by_.clear(); }
add_target_installed_by(std::string value)17469   void add_target_installed_by(std::string value) { target_installed_by_.emplace_back(value); }
add_target_installed_by()17470   std::string* add_target_installed_by() { target_installed_by_.emplace_back(); return &target_installed_by_.back(); }
17471 
heaps() const17472   const std::vector<std::string>& heaps() const { return heaps_; }
mutable_heaps()17473   std::vector<std::string>* mutable_heaps() { return &heaps_; }
heaps_size() const17474   int heaps_size() const { return static_cast<int>(heaps_.size()); }
clear_heaps()17475   void clear_heaps() { heaps_.clear(); }
add_heaps(std::string value)17476   void add_heaps(std::string value) { heaps_.emplace_back(value); }
add_heaps()17477   std::string* add_heaps() { heaps_.emplace_back(); return &heaps_.back(); }
17478 
exclude_heaps() const17479   const std::vector<std::string>& exclude_heaps() const { return exclude_heaps_; }
mutable_exclude_heaps()17480   std::vector<std::string>* mutable_exclude_heaps() { return &exclude_heaps_; }
exclude_heaps_size() const17481   int exclude_heaps_size() const { return static_cast<int>(exclude_heaps_.size()); }
clear_exclude_heaps()17482   void clear_exclude_heaps() { exclude_heaps_.clear(); }
add_exclude_heaps(std::string value)17483   void add_exclude_heaps(std::string value) { exclude_heaps_.emplace_back(value); }
add_exclude_heaps()17484   std::string* add_exclude_heaps() { exclude_heaps_.emplace_back(); return &exclude_heaps_.back(); }
17485 
has_stream_allocations() const17486   bool has_stream_allocations() const { return _has_field_[23]; }
stream_allocations() const17487   bool stream_allocations() const { return stream_allocations_; }
set_stream_allocations(bool value)17488   void set_stream_allocations(bool value) { stream_allocations_ = value; _has_field_.set(23); }
17489 
heap_sampling_intervals() const17490   const std::vector<uint64_t>& heap_sampling_intervals() const { return heap_sampling_intervals_; }
mutable_heap_sampling_intervals()17491   std::vector<uint64_t>* mutable_heap_sampling_intervals() { return &heap_sampling_intervals_; }
heap_sampling_intervals_size() const17492   int heap_sampling_intervals_size() const { return static_cast<int>(heap_sampling_intervals_.size()); }
clear_heap_sampling_intervals()17493   void clear_heap_sampling_intervals() { heap_sampling_intervals_.clear(); }
add_heap_sampling_intervals(uint64_t value)17494   void add_heap_sampling_intervals(uint64_t value) { heap_sampling_intervals_.emplace_back(value); }
add_heap_sampling_intervals()17495   uint64_t* add_heap_sampling_intervals() { heap_sampling_intervals_.emplace_back(); return &heap_sampling_intervals_.back(); }
17496 
has_all_heaps() const17497   bool has_all_heaps() const { return _has_field_[21]; }
all_heaps() const17498   bool all_heaps() const { return all_heaps_; }
set_all_heaps(bool value)17499   void set_all_heaps(bool value) { all_heaps_ = value; _has_field_.set(21); }
17500 
has_all() const17501   bool has_all() const { return _has_field_[5]; }
all() const17502   bool all() const { return all_; }
set_all(bool value)17503   void set_all(bool value) { all_ = value; _has_field_.set(5); }
17504 
has_min_anonymous_memory_kb() const17505   bool has_min_anonymous_memory_kb() const { return _has_field_[15]; }
min_anonymous_memory_kb() const17506   uint32_t min_anonymous_memory_kb() const { return min_anonymous_memory_kb_; }
set_min_anonymous_memory_kb(uint32_t value)17507   void set_min_anonymous_memory_kb(uint32_t value) { min_anonymous_memory_kb_ = value; _has_field_.set(15); }
17508 
has_max_heapprofd_memory_kb() const17509   bool has_max_heapprofd_memory_kb() const { return _has_field_[16]; }
max_heapprofd_memory_kb() const17510   uint32_t max_heapprofd_memory_kb() const { return max_heapprofd_memory_kb_; }
set_max_heapprofd_memory_kb(uint32_t value)17511   void set_max_heapprofd_memory_kb(uint32_t value) { max_heapprofd_memory_kb_ = value; _has_field_.set(16); }
17512 
has_max_heapprofd_cpu_secs() const17513   bool has_max_heapprofd_cpu_secs() const { return _has_field_[17]; }
max_heapprofd_cpu_secs() const17514   uint64_t max_heapprofd_cpu_secs() const { return max_heapprofd_cpu_secs_; }
set_max_heapprofd_cpu_secs(uint64_t value)17515   void set_max_heapprofd_cpu_secs(uint64_t value) { max_heapprofd_cpu_secs_ = value; _has_field_.set(17); }
17516 
skip_symbol_prefix() const17517   const std::vector<std::string>& skip_symbol_prefix() const { return skip_symbol_prefix_; }
mutable_skip_symbol_prefix()17518   std::vector<std::string>* mutable_skip_symbol_prefix() { return &skip_symbol_prefix_; }
skip_symbol_prefix_size() const17519   int skip_symbol_prefix_size() const { return static_cast<int>(skip_symbol_prefix_.size()); }
clear_skip_symbol_prefix()17520   void clear_skip_symbol_prefix() { skip_symbol_prefix_.clear(); }
add_skip_symbol_prefix(std::string value)17521   void add_skip_symbol_prefix(std::string value) { skip_symbol_prefix_.emplace_back(value); }
add_skip_symbol_prefix()17522   std::string* add_skip_symbol_prefix() { skip_symbol_prefix_.emplace_back(); return &skip_symbol_prefix_.back(); }
17523 
has_continuous_dump_config() const17524   bool has_continuous_dump_config() const { return _has_field_[6]; }
continuous_dump_config() const17525   const HeapprofdConfig_ContinuousDumpConfig& continuous_dump_config() const { return *continuous_dump_config_; }
mutable_continuous_dump_config()17526   HeapprofdConfig_ContinuousDumpConfig* mutable_continuous_dump_config() { _has_field_.set(6); return continuous_dump_config_.get(); }
17527 
has_shmem_size_bytes() const17528   bool has_shmem_size_bytes() const { return _has_field_[8]; }
shmem_size_bytes() const17529   uint64_t shmem_size_bytes() const { return shmem_size_bytes_; }
set_shmem_size_bytes(uint64_t value)17530   void set_shmem_size_bytes(uint64_t value) { shmem_size_bytes_ = value; _has_field_.set(8); }
17531 
has_block_client() const17532   bool has_block_client() const { return _has_field_[9]; }
block_client() const17533   bool block_client() const { return block_client_; }
set_block_client(bool value)17534   void set_block_client(bool value) { block_client_ = value; _has_field_.set(9); }
17535 
has_block_client_timeout_us() const17536   bool has_block_client_timeout_us() const { return _has_field_[14]; }
block_client_timeout_us() const17537   uint32_t block_client_timeout_us() const { return block_client_timeout_us_; }
set_block_client_timeout_us(uint32_t value)17538   void set_block_client_timeout_us(uint32_t value) { block_client_timeout_us_ = value; _has_field_.set(14); }
17539 
has_no_startup() const17540   bool has_no_startup() const { return _has_field_[10]; }
no_startup() const17541   bool no_startup() const { return no_startup_; }
set_no_startup(bool value)17542   void set_no_startup(bool value) { no_startup_ = value; _has_field_.set(10); }
17543 
has_no_running() const17544   bool has_no_running() const { return _has_field_[11]; }
no_running() const17545   bool no_running() const { return no_running_; }
set_no_running(bool value)17546   void set_no_running(bool value) { no_running_ = value; _has_field_.set(11); }
17547 
has_dump_at_max() const17548   bool has_dump_at_max() const { return _has_field_[13]; }
dump_at_max() const17549   bool dump_at_max() const { return dump_at_max_; }
set_dump_at_max(bool value)17550   void set_dump_at_max(bool value) { dump_at_max_ = value; _has_field_.set(13); }
17551 
has_disable_fork_teardown() const17552   bool has_disable_fork_teardown() const { return _has_field_[18]; }
disable_fork_teardown() const17553   bool disable_fork_teardown() const { return disable_fork_teardown_; }
set_disable_fork_teardown(bool value)17554   void set_disable_fork_teardown(bool value) { disable_fork_teardown_ = value; _has_field_.set(18); }
17555 
has_disable_vfork_detection() const17556   bool has_disable_vfork_detection() const { return _has_field_[19]; }
disable_vfork_detection() const17557   bool disable_vfork_detection() const { return disable_vfork_detection_; }
set_disable_vfork_detection(bool value)17558   void set_disable_vfork_detection(bool value) { disable_vfork_detection_ = value; _has_field_.set(19); }
17559 
17560  private:
17561   uint64_t sampling_interval_bytes_{};
17562   uint64_t adaptive_sampling_shmem_threshold_{};
17563   uint64_t adaptive_sampling_max_sampling_interval_bytes_{};
17564   std::vector<std::string> process_cmdline_;
17565   std::vector<uint64_t> pid_;
17566   std::vector<std::string> target_installed_by_;
17567   std::vector<std::string> heaps_;
17568   std::vector<std::string> exclude_heaps_;
17569   bool stream_allocations_{};
17570   std::vector<uint64_t> heap_sampling_intervals_;
17571   bool all_heaps_{};
17572   bool all_{};
17573   uint32_t min_anonymous_memory_kb_{};
17574   uint32_t max_heapprofd_memory_kb_{};
17575   uint64_t max_heapprofd_cpu_secs_{};
17576   std::vector<std::string> skip_symbol_prefix_;
17577   ::protozero::CopyablePtr<HeapprofdConfig_ContinuousDumpConfig> continuous_dump_config_;
17578   uint64_t shmem_size_bytes_{};
17579   bool block_client_{};
17580   uint32_t block_client_timeout_us_{};
17581   bool no_startup_{};
17582   bool no_running_{};
17583   bool dump_at_max_{};
17584   bool disable_fork_teardown_{};
17585   bool disable_vfork_detection_{};
17586 
17587   // Allows to preserve unknown protobuf fields for compatibility
17588   // with future versions of .proto files.
17589   std::string unknown_fields_;
17590 
17591   std::bitset<28> _has_field_{};
17592 };
17593 
17594 
17595 class PERFETTO_EXPORT HeapprofdConfig_ContinuousDumpConfig : public ::protozero::CppMessageObj {
17596  public:
17597   enum FieldNumbers {
17598     kDumpPhaseMsFieldNumber = 5,
17599     kDumpIntervalMsFieldNumber = 6,
17600   };
17601 
17602   HeapprofdConfig_ContinuousDumpConfig();
17603   ~HeapprofdConfig_ContinuousDumpConfig() override;
17604   HeapprofdConfig_ContinuousDumpConfig(HeapprofdConfig_ContinuousDumpConfig&&) noexcept;
17605   HeapprofdConfig_ContinuousDumpConfig& operator=(HeapprofdConfig_ContinuousDumpConfig&&);
17606   HeapprofdConfig_ContinuousDumpConfig(const HeapprofdConfig_ContinuousDumpConfig&);
17607   HeapprofdConfig_ContinuousDumpConfig& operator=(const HeapprofdConfig_ContinuousDumpConfig&);
17608   bool operator==(const HeapprofdConfig_ContinuousDumpConfig&) const;
operator !=(const HeapprofdConfig_ContinuousDumpConfig & other) const17609   bool operator!=(const HeapprofdConfig_ContinuousDumpConfig& other) const { return !(*this == other); }
17610 
17611   bool ParseFromArray(const void*, size_t) override;
17612   std::string SerializeAsString() const override;
17613   std::vector<uint8_t> SerializeAsArray() const override;
17614   void Serialize(::protozero::Message*) const;
17615 
has_dump_phase_ms() const17616   bool has_dump_phase_ms() const { return _has_field_[5]; }
dump_phase_ms() const17617   uint32_t dump_phase_ms() const { return dump_phase_ms_; }
set_dump_phase_ms(uint32_t value)17618   void set_dump_phase_ms(uint32_t value) { dump_phase_ms_ = value; _has_field_.set(5); }
17619 
has_dump_interval_ms() const17620   bool has_dump_interval_ms() const { return _has_field_[6]; }
dump_interval_ms() const17621   uint32_t dump_interval_ms() const { return dump_interval_ms_; }
set_dump_interval_ms(uint32_t value)17622   void set_dump_interval_ms(uint32_t value) { dump_interval_ms_ = value; _has_field_.set(6); }
17623 
17624  private:
17625   uint32_t dump_phase_ms_{};
17626   uint32_t dump_interval_ms_{};
17627 
17628   // Allows to preserve unknown protobuf fields for compatibility
17629   // with future versions of .proto files.
17630   std::string unknown_fields_;
17631 
17632   std::bitset<7> _has_field_{};
17633 };
17634 
17635 }  // namespace perfetto
17636 }  // namespace protos
17637 }  // namespace gen
17638 
17639 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_HEAPPROFD_CONFIG_PROTO_CPP_H_
17640 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
17641 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
17642 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
17643 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
17644 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
17645 #if defined(__GNUC__) || defined(__clang__)
17646 #pragma GCC diagnostic push
17647 #pragma GCC diagnostic ignored "-Wfloat-equal"
17648 #endif
17649 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/heapprofd_config.gen.h"
17650 
17651 namespace perfetto {
17652 namespace protos {
17653 namespace gen {
17654 
17655 HeapprofdConfig::HeapprofdConfig() = default;
17656 HeapprofdConfig::~HeapprofdConfig() = default;
17657 HeapprofdConfig::HeapprofdConfig(const HeapprofdConfig&) = default;
17658 HeapprofdConfig& HeapprofdConfig::operator=(const HeapprofdConfig&) = default;
17659 HeapprofdConfig::HeapprofdConfig(HeapprofdConfig&&) noexcept = default;
17660 HeapprofdConfig& HeapprofdConfig::operator=(HeapprofdConfig&&) = default;
17661 
operator ==(const HeapprofdConfig & other) const17662 bool HeapprofdConfig::operator==(const HeapprofdConfig& other) const {
17663   return unknown_fields_ == other.unknown_fields_
17664    && sampling_interval_bytes_ == other.sampling_interval_bytes_
17665    && adaptive_sampling_shmem_threshold_ == other.adaptive_sampling_shmem_threshold_
17666    && adaptive_sampling_max_sampling_interval_bytes_ == other.adaptive_sampling_max_sampling_interval_bytes_
17667    && process_cmdline_ == other.process_cmdline_
17668    && pid_ == other.pid_
17669    && target_installed_by_ == other.target_installed_by_
17670    && heaps_ == other.heaps_
17671    && exclude_heaps_ == other.exclude_heaps_
17672    && stream_allocations_ == other.stream_allocations_
17673    && heap_sampling_intervals_ == other.heap_sampling_intervals_
17674    && all_heaps_ == other.all_heaps_
17675    && all_ == other.all_
17676    && min_anonymous_memory_kb_ == other.min_anonymous_memory_kb_
17677    && max_heapprofd_memory_kb_ == other.max_heapprofd_memory_kb_
17678    && max_heapprofd_cpu_secs_ == other.max_heapprofd_cpu_secs_
17679    && skip_symbol_prefix_ == other.skip_symbol_prefix_
17680    && continuous_dump_config_ == other.continuous_dump_config_
17681    && shmem_size_bytes_ == other.shmem_size_bytes_
17682    && block_client_ == other.block_client_
17683    && block_client_timeout_us_ == other.block_client_timeout_us_
17684    && no_startup_ == other.no_startup_
17685    && no_running_ == other.no_running_
17686    && dump_at_max_ == other.dump_at_max_
17687    && disable_fork_teardown_ == other.disable_fork_teardown_
17688    && disable_vfork_detection_ == other.disable_vfork_detection_;
17689 }
17690 
ParseFromArray(const void * raw,size_t size)17691 bool HeapprofdConfig::ParseFromArray(const void* raw, size_t size) {
17692   process_cmdline_.clear();
17693   pid_.clear();
17694   target_installed_by_.clear();
17695   heaps_.clear();
17696   exclude_heaps_.clear();
17697   heap_sampling_intervals_.clear();
17698   skip_symbol_prefix_.clear();
17699   unknown_fields_.clear();
17700   bool packed_error = false;
17701 
17702   ::protozero::ProtoDecoder dec(raw, size);
17703   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
17704     if (field.id() < _has_field_.size()) {
17705       _has_field_.set(field.id());
17706     }
17707     switch (field.id()) {
17708       case 1 /* sampling_interval_bytes */:
17709         field.get(&sampling_interval_bytes_);
17710         break;
17711       case 24 /* adaptive_sampling_shmem_threshold */:
17712         field.get(&adaptive_sampling_shmem_threshold_);
17713         break;
17714       case 25 /* adaptive_sampling_max_sampling_interval_bytes */:
17715         field.get(&adaptive_sampling_max_sampling_interval_bytes_);
17716         break;
17717       case 2 /* process_cmdline */:
17718         process_cmdline_.emplace_back();
17719         field.get(&process_cmdline_.back());
17720         break;
17721       case 4 /* pid */:
17722         pid_.emplace_back();
17723         field.get(&pid_.back());
17724         break;
17725       case 26 /* target_installed_by */:
17726         target_installed_by_.emplace_back();
17727         field.get(&target_installed_by_.back());
17728         break;
17729       case 20 /* heaps */:
17730         heaps_.emplace_back();
17731         field.get(&heaps_.back());
17732         break;
17733       case 27 /* exclude_heaps */:
17734         exclude_heaps_.emplace_back();
17735         field.get(&exclude_heaps_.back());
17736         break;
17737       case 23 /* stream_allocations */:
17738         field.get(&stream_allocations_);
17739         break;
17740       case 22 /* heap_sampling_intervals */:
17741         heap_sampling_intervals_.emplace_back();
17742         field.get(&heap_sampling_intervals_.back());
17743         break;
17744       case 21 /* all_heaps */:
17745         field.get(&all_heaps_);
17746         break;
17747       case 5 /* all */:
17748         field.get(&all_);
17749         break;
17750       case 15 /* min_anonymous_memory_kb */:
17751         field.get(&min_anonymous_memory_kb_);
17752         break;
17753       case 16 /* max_heapprofd_memory_kb */:
17754         field.get(&max_heapprofd_memory_kb_);
17755         break;
17756       case 17 /* max_heapprofd_cpu_secs */:
17757         field.get(&max_heapprofd_cpu_secs_);
17758         break;
17759       case 7 /* skip_symbol_prefix */:
17760         skip_symbol_prefix_.emplace_back();
17761         field.get(&skip_symbol_prefix_.back());
17762         break;
17763       case 6 /* continuous_dump_config */:
17764         (*continuous_dump_config_).ParseFromArray(field.data(), field.size());
17765         break;
17766       case 8 /* shmem_size_bytes */:
17767         field.get(&shmem_size_bytes_);
17768         break;
17769       case 9 /* block_client */:
17770         field.get(&block_client_);
17771         break;
17772       case 14 /* block_client_timeout_us */:
17773         field.get(&block_client_timeout_us_);
17774         break;
17775       case 10 /* no_startup */:
17776         field.get(&no_startup_);
17777         break;
17778       case 11 /* no_running */:
17779         field.get(&no_running_);
17780         break;
17781       case 13 /* dump_at_max */:
17782         field.get(&dump_at_max_);
17783         break;
17784       case 18 /* disable_fork_teardown */:
17785         field.get(&disable_fork_teardown_);
17786         break;
17787       case 19 /* disable_vfork_detection */:
17788         field.get(&disable_vfork_detection_);
17789         break;
17790       default:
17791         field.SerializeAndAppendTo(&unknown_fields_);
17792         break;
17793     }
17794   }
17795   return !packed_error && !dec.bytes_left();
17796 }
17797 
SerializeAsString() const17798 std::string HeapprofdConfig::SerializeAsString() const {
17799   ::protozero::HeapBuffered<::protozero::Message> msg;
17800   Serialize(msg.get());
17801   return msg.SerializeAsString();
17802 }
17803 
SerializeAsArray() const17804 std::vector<uint8_t> HeapprofdConfig::SerializeAsArray() const {
17805   ::protozero::HeapBuffered<::protozero::Message> msg;
17806   Serialize(msg.get());
17807   return msg.SerializeAsArray();
17808 }
17809 
Serialize(::protozero::Message * msg) const17810 void HeapprofdConfig::Serialize(::protozero::Message* msg) const {
17811   // Field 1: sampling_interval_bytes
17812   if (_has_field_[1]) {
17813     msg->AppendVarInt(1, sampling_interval_bytes_);
17814   }
17815 
17816   // Field 24: adaptive_sampling_shmem_threshold
17817   if (_has_field_[24]) {
17818     msg->AppendVarInt(24, adaptive_sampling_shmem_threshold_);
17819   }
17820 
17821   // Field 25: adaptive_sampling_max_sampling_interval_bytes
17822   if (_has_field_[25]) {
17823     msg->AppendVarInt(25, adaptive_sampling_max_sampling_interval_bytes_);
17824   }
17825 
17826   // Field 2: process_cmdline
17827   for (auto& it : process_cmdline_) {
17828     msg->AppendString(2, it);
17829   }
17830 
17831   // Field 4: pid
17832   for (auto& it : pid_) {
17833     msg->AppendVarInt(4, it);
17834   }
17835 
17836   // Field 26: target_installed_by
17837   for (auto& it : target_installed_by_) {
17838     msg->AppendString(26, it);
17839   }
17840 
17841   // Field 20: heaps
17842   for (auto& it : heaps_) {
17843     msg->AppendString(20, it);
17844   }
17845 
17846   // Field 27: exclude_heaps
17847   for (auto& it : exclude_heaps_) {
17848     msg->AppendString(27, it);
17849   }
17850 
17851   // Field 23: stream_allocations
17852   if (_has_field_[23]) {
17853     msg->AppendTinyVarInt(23, stream_allocations_);
17854   }
17855 
17856   // Field 22: heap_sampling_intervals
17857   for (auto& it : heap_sampling_intervals_) {
17858     msg->AppendVarInt(22, it);
17859   }
17860 
17861   // Field 21: all_heaps
17862   if (_has_field_[21]) {
17863     msg->AppendTinyVarInt(21, all_heaps_);
17864   }
17865 
17866   // Field 5: all
17867   if (_has_field_[5]) {
17868     msg->AppendTinyVarInt(5, all_);
17869   }
17870 
17871   // Field 15: min_anonymous_memory_kb
17872   if (_has_field_[15]) {
17873     msg->AppendVarInt(15, min_anonymous_memory_kb_);
17874   }
17875 
17876   // Field 16: max_heapprofd_memory_kb
17877   if (_has_field_[16]) {
17878     msg->AppendVarInt(16, max_heapprofd_memory_kb_);
17879   }
17880 
17881   // Field 17: max_heapprofd_cpu_secs
17882   if (_has_field_[17]) {
17883     msg->AppendVarInt(17, max_heapprofd_cpu_secs_);
17884   }
17885 
17886   // Field 7: skip_symbol_prefix
17887   for (auto& it : skip_symbol_prefix_) {
17888     msg->AppendString(7, it);
17889   }
17890 
17891   // Field 6: continuous_dump_config
17892   if (_has_field_[6]) {
17893     (*continuous_dump_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
17894   }
17895 
17896   // Field 8: shmem_size_bytes
17897   if (_has_field_[8]) {
17898     msg->AppendVarInt(8, shmem_size_bytes_);
17899   }
17900 
17901   // Field 9: block_client
17902   if (_has_field_[9]) {
17903     msg->AppendTinyVarInt(9, block_client_);
17904   }
17905 
17906   // Field 14: block_client_timeout_us
17907   if (_has_field_[14]) {
17908     msg->AppendVarInt(14, block_client_timeout_us_);
17909   }
17910 
17911   // Field 10: no_startup
17912   if (_has_field_[10]) {
17913     msg->AppendTinyVarInt(10, no_startup_);
17914   }
17915 
17916   // Field 11: no_running
17917   if (_has_field_[11]) {
17918     msg->AppendTinyVarInt(11, no_running_);
17919   }
17920 
17921   // Field 13: dump_at_max
17922   if (_has_field_[13]) {
17923     msg->AppendTinyVarInt(13, dump_at_max_);
17924   }
17925 
17926   // Field 18: disable_fork_teardown
17927   if (_has_field_[18]) {
17928     msg->AppendTinyVarInt(18, disable_fork_teardown_);
17929   }
17930 
17931   // Field 19: disable_vfork_detection
17932   if (_has_field_[19]) {
17933     msg->AppendTinyVarInt(19, disable_vfork_detection_);
17934   }
17935 
17936   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
17937 }
17938 
17939 
17940 HeapprofdConfig_ContinuousDumpConfig::HeapprofdConfig_ContinuousDumpConfig() = default;
17941 HeapprofdConfig_ContinuousDumpConfig::~HeapprofdConfig_ContinuousDumpConfig() = default;
17942 HeapprofdConfig_ContinuousDumpConfig::HeapprofdConfig_ContinuousDumpConfig(const HeapprofdConfig_ContinuousDumpConfig&) = default;
17943 HeapprofdConfig_ContinuousDumpConfig& HeapprofdConfig_ContinuousDumpConfig::operator=(const HeapprofdConfig_ContinuousDumpConfig&) = default;
17944 HeapprofdConfig_ContinuousDumpConfig::HeapprofdConfig_ContinuousDumpConfig(HeapprofdConfig_ContinuousDumpConfig&&) noexcept = default;
17945 HeapprofdConfig_ContinuousDumpConfig& HeapprofdConfig_ContinuousDumpConfig::operator=(HeapprofdConfig_ContinuousDumpConfig&&) = default;
17946 
operator ==(const HeapprofdConfig_ContinuousDumpConfig & other) const17947 bool HeapprofdConfig_ContinuousDumpConfig::operator==(const HeapprofdConfig_ContinuousDumpConfig& other) const {
17948   return unknown_fields_ == other.unknown_fields_
17949    && dump_phase_ms_ == other.dump_phase_ms_
17950    && dump_interval_ms_ == other.dump_interval_ms_;
17951 }
17952 
ParseFromArray(const void * raw,size_t size)17953 bool HeapprofdConfig_ContinuousDumpConfig::ParseFromArray(const void* raw, size_t size) {
17954   unknown_fields_.clear();
17955   bool packed_error = false;
17956 
17957   ::protozero::ProtoDecoder dec(raw, size);
17958   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
17959     if (field.id() < _has_field_.size()) {
17960       _has_field_.set(field.id());
17961     }
17962     switch (field.id()) {
17963       case 5 /* dump_phase_ms */:
17964         field.get(&dump_phase_ms_);
17965         break;
17966       case 6 /* dump_interval_ms */:
17967         field.get(&dump_interval_ms_);
17968         break;
17969       default:
17970         field.SerializeAndAppendTo(&unknown_fields_);
17971         break;
17972     }
17973   }
17974   return !packed_error && !dec.bytes_left();
17975 }
17976 
SerializeAsString() const17977 std::string HeapprofdConfig_ContinuousDumpConfig::SerializeAsString() const {
17978   ::protozero::HeapBuffered<::protozero::Message> msg;
17979   Serialize(msg.get());
17980   return msg.SerializeAsString();
17981 }
17982 
SerializeAsArray() const17983 std::vector<uint8_t> HeapprofdConfig_ContinuousDumpConfig::SerializeAsArray() const {
17984   ::protozero::HeapBuffered<::protozero::Message> msg;
17985   Serialize(msg.get());
17986   return msg.SerializeAsArray();
17987 }
17988 
Serialize(::protozero::Message * msg) const17989 void HeapprofdConfig_ContinuousDumpConfig::Serialize(::protozero::Message* msg) const {
17990   // Field 5: dump_phase_ms
17991   if (_has_field_[5]) {
17992     msg->AppendVarInt(5, dump_phase_ms_);
17993   }
17994 
17995   // Field 6: dump_interval_ms
17996   if (_has_field_[6]) {
17997     msg->AppendVarInt(6, dump_interval_ms_);
17998   }
17999 
18000   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
18001 }
18002 
18003 }  // namespace perfetto
18004 }  // namespace protos
18005 }  // namespace gen
18006 #if defined(__GNUC__) || defined(__clang__)
18007 #pragma GCC diagnostic pop
18008 #endif
18009 // gen_amalgamated begin source: gen/protos/perfetto/config/profiling/java_hprof_config.gen.cc
18010 // gen_amalgamated begin header: gen/protos/perfetto/config/profiling/java_hprof_config.gen.h
18011 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
18012 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_JAVA_HPROF_CONFIG_PROTO_CPP_H_
18013 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_JAVA_HPROF_CONFIG_PROTO_CPP_H_
18014 
18015 #include <stdint.h>
18016 #include <bitset>
18017 #include <vector>
18018 #include <string>
18019 #include <type_traits>
18020 
18021 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
18022 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
18023 // gen_amalgamated expanded: #include "perfetto/base/export.h"
18024 
18025 namespace perfetto {
18026 namespace protos {
18027 namespace gen {
18028 class JavaHprofConfig;
18029 class JavaHprofConfig_ContinuousDumpConfig;
18030 }  // namespace perfetto
18031 }  // namespace protos
18032 }  // namespace gen
18033 
18034 namespace protozero {
18035 class Message;
18036 }  // namespace protozero
18037 
18038 namespace perfetto {
18039 namespace protos {
18040 namespace gen {
18041 
18042 class PERFETTO_EXPORT JavaHprofConfig : public ::protozero::CppMessageObj {
18043  public:
18044   using ContinuousDumpConfig = JavaHprofConfig_ContinuousDumpConfig;
18045   enum FieldNumbers {
18046     kProcessCmdlineFieldNumber = 1,
18047     kPidFieldNumber = 2,
18048     kTargetInstalledByFieldNumber = 7,
18049     kContinuousDumpConfigFieldNumber = 3,
18050     kMinAnonymousMemoryKbFieldNumber = 4,
18051     kDumpSmapsFieldNumber = 5,
18052     kIgnoredTypesFieldNumber = 6,
18053   };
18054 
18055   JavaHprofConfig();
18056   ~JavaHprofConfig() override;
18057   JavaHprofConfig(JavaHprofConfig&&) noexcept;
18058   JavaHprofConfig& operator=(JavaHprofConfig&&);
18059   JavaHprofConfig(const JavaHprofConfig&);
18060   JavaHprofConfig& operator=(const JavaHprofConfig&);
18061   bool operator==(const JavaHprofConfig&) const;
operator !=(const JavaHprofConfig & other) const18062   bool operator!=(const JavaHprofConfig& other) const { return !(*this == other); }
18063 
18064   bool ParseFromArray(const void*, size_t) override;
18065   std::string SerializeAsString() const override;
18066   std::vector<uint8_t> SerializeAsArray() const override;
18067   void Serialize(::protozero::Message*) const;
18068 
process_cmdline() const18069   const std::vector<std::string>& process_cmdline() const { return process_cmdline_; }
mutable_process_cmdline()18070   std::vector<std::string>* mutable_process_cmdline() { return &process_cmdline_; }
process_cmdline_size() const18071   int process_cmdline_size() const { return static_cast<int>(process_cmdline_.size()); }
clear_process_cmdline()18072   void clear_process_cmdline() { process_cmdline_.clear(); }
add_process_cmdline(std::string value)18073   void add_process_cmdline(std::string value) { process_cmdline_.emplace_back(value); }
add_process_cmdline()18074   std::string* add_process_cmdline() { process_cmdline_.emplace_back(); return &process_cmdline_.back(); }
18075 
pid() const18076   const std::vector<uint64_t>& pid() const { return pid_; }
mutable_pid()18077   std::vector<uint64_t>* mutable_pid() { return &pid_; }
pid_size() const18078   int pid_size() const { return static_cast<int>(pid_.size()); }
clear_pid()18079   void clear_pid() { pid_.clear(); }
add_pid(uint64_t value)18080   void add_pid(uint64_t value) { pid_.emplace_back(value); }
add_pid()18081   uint64_t* add_pid() { pid_.emplace_back(); return &pid_.back(); }
18082 
target_installed_by() const18083   const std::vector<std::string>& target_installed_by() const { return target_installed_by_; }
mutable_target_installed_by()18084   std::vector<std::string>* mutable_target_installed_by() { return &target_installed_by_; }
target_installed_by_size() const18085   int target_installed_by_size() const { return static_cast<int>(target_installed_by_.size()); }
clear_target_installed_by()18086   void clear_target_installed_by() { target_installed_by_.clear(); }
add_target_installed_by(std::string value)18087   void add_target_installed_by(std::string value) { target_installed_by_.emplace_back(value); }
add_target_installed_by()18088   std::string* add_target_installed_by() { target_installed_by_.emplace_back(); return &target_installed_by_.back(); }
18089 
has_continuous_dump_config() const18090   bool has_continuous_dump_config() const { return _has_field_[3]; }
continuous_dump_config() const18091   const JavaHprofConfig_ContinuousDumpConfig& continuous_dump_config() const { return *continuous_dump_config_; }
mutable_continuous_dump_config()18092   JavaHprofConfig_ContinuousDumpConfig* mutable_continuous_dump_config() { _has_field_.set(3); return continuous_dump_config_.get(); }
18093 
has_min_anonymous_memory_kb() const18094   bool has_min_anonymous_memory_kb() const { return _has_field_[4]; }
min_anonymous_memory_kb() const18095   uint32_t min_anonymous_memory_kb() const { return min_anonymous_memory_kb_; }
set_min_anonymous_memory_kb(uint32_t value)18096   void set_min_anonymous_memory_kb(uint32_t value) { min_anonymous_memory_kb_ = value; _has_field_.set(4); }
18097 
has_dump_smaps() const18098   bool has_dump_smaps() const { return _has_field_[5]; }
dump_smaps() const18099   bool dump_smaps() const { return dump_smaps_; }
set_dump_smaps(bool value)18100   void set_dump_smaps(bool value) { dump_smaps_ = value; _has_field_.set(5); }
18101 
ignored_types() const18102   const std::vector<std::string>& ignored_types() const { return ignored_types_; }
mutable_ignored_types()18103   std::vector<std::string>* mutable_ignored_types() { return &ignored_types_; }
ignored_types_size() const18104   int ignored_types_size() const { return static_cast<int>(ignored_types_.size()); }
clear_ignored_types()18105   void clear_ignored_types() { ignored_types_.clear(); }
add_ignored_types(std::string value)18106   void add_ignored_types(std::string value) { ignored_types_.emplace_back(value); }
add_ignored_types()18107   std::string* add_ignored_types() { ignored_types_.emplace_back(); return &ignored_types_.back(); }
18108 
18109  private:
18110   std::vector<std::string> process_cmdline_;
18111   std::vector<uint64_t> pid_;
18112   std::vector<std::string> target_installed_by_;
18113   ::protozero::CopyablePtr<JavaHprofConfig_ContinuousDumpConfig> continuous_dump_config_;
18114   uint32_t min_anonymous_memory_kb_{};
18115   bool dump_smaps_{};
18116   std::vector<std::string> ignored_types_;
18117 
18118   // Allows to preserve unknown protobuf fields for compatibility
18119   // with future versions of .proto files.
18120   std::string unknown_fields_;
18121 
18122   std::bitset<8> _has_field_{};
18123 };
18124 
18125 
18126 class PERFETTO_EXPORT JavaHprofConfig_ContinuousDumpConfig : public ::protozero::CppMessageObj {
18127  public:
18128   enum FieldNumbers {
18129     kDumpPhaseMsFieldNumber = 1,
18130     kDumpIntervalMsFieldNumber = 2,
18131   };
18132 
18133   JavaHprofConfig_ContinuousDumpConfig();
18134   ~JavaHprofConfig_ContinuousDumpConfig() override;
18135   JavaHprofConfig_ContinuousDumpConfig(JavaHprofConfig_ContinuousDumpConfig&&) noexcept;
18136   JavaHprofConfig_ContinuousDumpConfig& operator=(JavaHprofConfig_ContinuousDumpConfig&&);
18137   JavaHprofConfig_ContinuousDumpConfig(const JavaHprofConfig_ContinuousDumpConfig&);
18138   JavaHprofConfig_ContinuousDumpConfig& operator=(const JavaHprofConfig_ContinuousDumpConfig&);
18139   bool operator==(const JavaHprofConfig_ContinuousDumpConfig&) const;
operator !=(const JavaHprofConfig_ContinuousDumpConfig & other) const18140   bool operator!=(const JavaHprofConfig_ContinuousDumpConfig& other) const { return !(*this == other); }
18141 
18142   bool ParseFromArray(const void*, size_t) override;
18143   std::string SerializeAsString() const override;
18144   std::vector<uint8_t> SerializeAsArray() const override;
18145   void Serialize(::protozero::Message*) const;
18146 
has_dump_phase_ms() const18147   bool has_dump_phase_ms() const { return _has_field_[1]; }
dump_phase_ms() const18148   uint32_t dump_phase_ms() const { return dump_phase_ms_; }
set_dump_phase_ms(uint32_t value)18149   void set_dump_phase_ms(uint32_t value) { dump_phase_ms_ = value; _has_field_.set(1); }
18150 
has_dump_interval_ms() const18151   bool has_dump_interval_ms() const { return _has_field_[2]; }
dump_interval_ms() const18152   uint32_t dump_interval_ms() const { return dump_interval_ms_; }
set_dump_interval_ms(uint32_t value)18153   void set_dump_interval_ms(uint32_t value) { dump_interval_ms_ = value; _has_field_.set(2); }
18154 
18155  private:
18156   uint32_t dump_phase_ms_{};
18157   uint32_t dump_interval_ms_{};
18158 
18159   // Allows to preserve unknown protobuf fields for compatibility
18160   // with future versions of .proto files.
18161   std::string unknown_fields_;
18162 
18163   std::bitset<3> _has_field_{};
18164 };
18165 
18166 }  // namespace perfetto
18167 }  // namespace protos
18168 }  // namespace gen
18169 
18170 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_JAVA_HPROF_CONFIG_PROTO_CPP_H_
18171 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
18172 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
18173 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
18174 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
18175 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
18176 #if defined(__GNUC__) || defined(__clang__)
18177 #pragma GCC diagnostic push
18178 #pragma GCC diagnostic ignored "-Wfloat-equal"
18179 #endif
18180 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/java_hprof_config.gen.h"
18181 
18182 namespace perfetto {
18183 namespace protos {
18184 namespace gen {
18185 
18186 JavaHprofConfig::JavaHprofConfig() = default;
18187 JavaHprofConfig::~JavaHprofConfig() = default;
18188 JavaHprofConfig::JavaHprofConfig(const JavaHprofConfig&) = default;
18189 JavaHprofConfig& JavaHprofConfig::operator=(const JavaHprofConfig&) = default;
18190 JavaHprofConfig::JavaHprofConfig(JavaHprofConfig&&) noexcept = default;
18191 JavaHprofConfig& JavaHprofConfig::operator=(JavaHprofConfig&&) = default;
18192 
operator ==(const JavaHprofConfig & other) const18193 bool JavaHprofConfig::operator==(const JavaHprofConfig& other) const {
18194   return unknown_fields_ == other.unknown_fields_
18195    && process_cmdline_ == other.process_cmdline_
18196    && pid_ == other.pid_
18197    && target_installed_by_ == other.target_installed_by_
18198    && continuous_dump_config_ == other.continuous_dump_config_
18199    && min_anonymous_memory_kb_ == other.min_anonymous_memory_kb_
18200    && dump_smaps_ == other.dump_smaps_
18201    && ignored_types_ == other.ignored_types_;
18202 }
18203 
ParseFromArray(const void * raw,size_t size)18204 bool JavaHprofConfig::ParseFromArray(const void* raw, size_t size) {
18205   process_cmdline_.clear();
18206   pid_.clear();
18207   target_installed_by_.clear();
18208   ignored_types_.clear();
18209   unknown_fields_.clear();
18210   bool packed_error = false;
18211 
18212   ::protozero::ProtoDecoder dec(raw, size);
18213   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
18214     if (field.id() < _has_field_.size()) {
18215       _has_field_.set(field.id());
18216     }
18217     switch (field.id()) {
18218       case 1 /* process_cmdline */:
18219         process_cmdline_.emplace_back();
18220         field.get(&process_cmdline_.back());
18221         break;
18222       case 2 /* pid */:
18223         pid_.emplace_back();
18224         field.get(&pid_.back());
18225         break;
18226       case 7 /* target_installed_by */:
18227         target_installed_by_.emplace_back();
18228         field.get(&target_installed_by_.back());
18229         break;
18230       case 3 /* continuous_dump_config */:
18231         (*continuous_dump_config_).ParseFromArray(field.data(), field.size());
18232         break;
18233       case 4 /* min_anonymous_memory_kb */:
18234         field.get(&min_anonymous_memory_kb_);
18235         break;
18236       case 5 /* dump_smaps */:
18237         field.get(&dump_smaps_);
18238         break;
18239       case 6 /* ignored_types */:
18240         ignored_types_.emplace_back();
18241         field.get(&ignored_types_.back());
18242         break;
18243       default:
18244         field.SerializeAndAppendTo(&unknown_fields_);
18245         break;
18246     }
18247   }
18248   return !packed_error && !dec.bytes_left();
18249 }
18250 
SerializeAsString() const18251 std::string JavaHprofConfig::SerializeAsString() const {
18252   ::protozero::HeapBuffered<::protozero::Message> msg;
18253   Serialize(msg.get());
18254   return msg.SerializeAsString();
18255 }
18256 
SerializeAsArray() const18257 std::vector<uint8_t> JavaHprofConfig::SerializeAsArray() const {
18258   ::protozero::HeapBuffered<::protozero::Message> msg;
18259   Serialize(msg.get());
18260   return msg.SerializeAsArray();
18261 }
18262 
Serialize(::protozero::Message * msg) const18263 void JavaHprofConfig::Serialize(::protozero::Message* msg) const {
18264   // Field 1: process_cmdline
18265   for (auto& it : process_cmdline_) {
18266     msg->AppendString(1, it);
18267   }
18268 
18269   // Field 2: pid
18270   for (auto& it : pid_) {
18271     msg->AppendVarInt(2, it);
18272   }
18273 
18274   // Field 7: target_installed_by
18275   for (auto& it : target_installed_by_) {
18276     msg->AppendString(7, it);
18277   }
18278 
18279   // Field 3: continuous_dump_config
18280   if (_has_field_[3]) {
18281     (*continuous_dump_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
18282   }
18283 
18284   // Field 4: min_anonymous_memory_kb
18285   if (_has_field_[4]) {
18286     msg->AppendVarInt(4, min_anonymous_memory_kb_);
18287   }
18288 
18289   // Field 5: dump_smaps
18290   if (_has_field_[5]) {
18291     msg->AppendTinyVarInt(5, dump_smaps_);
18292   }
18293 
18294   // Field 6: ignored_types
18295   for (auto& it : ignored_types_) {
18296     msg->AppendString(6, it);
18297   }
18298 
18299   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
18300 }
18301 
18302 
18303 JavaHprofConfig_ContinuousDumpConfig::JavaHprofConfig_ContinuousDumpConfig() = default;
18304 JavaHprofConfig_ContinuousDumpConfig::~JavaHprofConfig_ContinuousDumpConfig() = default;
18305 JavaHprofConfig_ContinuousDumpConfig::JavaHprofConfig_ContinuousDumpConfig(const JavaHprofConfig_ContinuousDumpConfig&) = default;
18306 JavaHprofConfig_ContinuousDumpConfig& JavaHprofConfig_ContinuousDumpConfig::operator=(const JavaHprofConfig_ContinuousDumpConfig&) = default;
18307 JavaHprofConfig_ContinuousDumpConfig::JavaHprofConfig_ContinuousDumpConfig(JavaHprofConfig_ContinuousDumpConfig&&) noexcept = default;
18308 JavaHprofConfig_ContinuousDumpConfig& JavaHprofConfig_ContinuousDumpConfig::operator=(JavaHprofConfig_ContinuousDumpConfig&&) = default;
18309 
operator ==(const JavaHprofConfig_ContinuousDumpConfig & other) const18310 bool JavaHprofConfig_ContinuousDumpConfig::operator==(const JavaHprofConfig_ContinuousDumpConfig& other) const {
18311   return unknown_fields_ == other.unknown_fields_
18312    && dump_phase_ms_ == other.dump_phase_ms_
18313    && dump_interval_ms_ == other.dump_interval_ms_;
18314 }
18315 
ParseFromArray(const void * raw,size_t size)18316 bool JavaHprofConfig_ContinuousDumpConfig::ParseFromArray(const void* raw, size_t size) {
18317   unknown_fields_.clear();
18318   bool packed_error = false;
18319 
18320   ::protozero::ProtoDecoder dec(raw, size);
18321   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
18322     if (field.id() < _has_field_.size()) {
18323       _has_field_.set(field.id());
18324     }
18325     switch (field.id()) {
18326       case 1 /* dump_phase_ms */:
18327         field.get(&dump_phase_ms_);
18328         break;
18329       case 2 /* dump_interval_ms */:
18330         field.get(&dump_interval_ms_);
18331         break;
18332       default:
18333         field.SerializeAndAppendTo(&unknown_fields_);
18334         break;
18335     }
18336   }
18337   return !packed_error && !dec.bytes_left();
18338 }
18339 
SerializeAsString() const18340 std::string JavaHprofConfig_ContinuousDumpConfig::SerializeAsString() const {
18341   ::protozero::HeapBuffered<::protozero::Message> msg;
18342   Serialize(msg.get());
18343   return msg.SerializeAsString();
18344 }
18345 
SerializeAsArray() const18346 std::vector<uint8_t> JavaHprofConfig_ContinuousDumpConfig::SerializeAsArray() const {
18347   ::protozero::HeapBuffered<::protozero::Message> msg;
18348   Serialize(msg.get());
18349   return msg.SerializeAsArray();
18350 }
18351 
Serialize(::protozero::Message * msg) const18352 void JavaHprofConfig_ContinuousDumpConfig::Serialize(::protozero::Message* msg) const {
18353   // Field 1: dump_phase_ms
18354   if (_has_field_[1]) {
18355     msg->AppendVarInt(1, dump_phase_ms_);
18356   }
18357 
18358   // Field 2: dump_interval_ms
18359   if (_has_field_[2]) {
18360     msg->AppendVarInt(2, dump_interval_ms_);
18361   }
18362 
18363   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
18364 }
18365 
18366 }  // namespace perfetto
18367 }  // namespace protos
18368 }  // namespace gen
18369 #if defined(__GNUC__) || defined(__clang__)
18370 #pragma GCC diagnostic pop
18371 #endif
18372 // gen_amalgamated begin source: gen/protos/perfetto/config/profiling/perf_event_config.gen.cc
18373 // gen_amalgamated begin header: gen/protos/perfetto/config/profiling/perf_event_config.gen.h
18374 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
18375 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_PERF_EVENT_CONFIG_PROTO_CPP_H_
18376 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_PERF_EVENT_CONFIG_PROTO_CPP_H_
18377 
18378 #include <stdint.h>
18379 #include <bitset>
18380 #include <vector>
18381 #include <string>
18382 #include <type_traits>
18383 
18384 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
18385 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
18386 // gen_amalgamated expanded: #include "perfetto/base/export.h"
18387 
18388 namespace perfetto {
18389 namespace protos {
18390 namespace gen {
18391 class PerfEventConfig;
18392 class PerfEventConfig_CallstackSampling;
18393 class PerfEventConfig_Scope;
18394 class PerfEvents_Timebase;
18395 class PerfEvents_Tracepoint;
18396 enum PerfEvents_Counter : int;
18397 }  // namespace perfetto
18398 }  // namespace protos
18399 }  // namespace gen
18400 
18401 namespace protozero {
18402 class Message;
18403 }  // namespace protozero
18404 
18405 namespace perfetto {
18406 namespace protos {
18407 namespace gen {
18408 
18409 class PERFETTO_EXPORT PerfEventConfig : public ::protozero::CppMessageObj {
18410  public:
18411   using CallstackSampling = PerfEventConfig_CallstackSampling;
18412   using Scope = PerfEventConfig_Scope;
18413   enum FieldNumbers {
18414     kTimebaseFieldNumber = 15,
18415     kCallstackSamplingFieldNumber = 16,
18416     kRingBufferReadPeriodMsFieldNumber = 8,
18417     kRingBufferPagesFieldNumber = 3,
18418     kMaxEnqueuedFootprintKbFieldNumber = 17,
18419     kMaxDaemonMemoryKbFieldNumber = 13,
18420     kRemoteDescriptorTimeoutMsFieldNumber = 9,
18421     kUnwindStateClearPeriodMsFieldNumber = 10,
18422     kAllCpusFieldNumber = 1,
18423     kSamplingFrequencyFieldNumber = 2,
18424     kKernelFramesFieldNumber = 12,
18425     kTargetPidFieldNumber = 4,
18426     kTargetCmdlineFieldNumber = 5,
18427     kTargetInstalledByFieldNumber = 18,
18428     kExcludePidFieldNumber = 6,
18429     kExcludeCmdlineFieldNumber = 7,
18430     kAdditionalCmdlineCountFieldNumber = 11,
18431   };
18432 
18433   PerfEventConfig();
18434   ~PerfEventConfig() override;
18435   PerfEventConfig(PerfEventConfig&&) noexcept;
18436   PerfEventConfig& operator=(PerfEventConfig&&);
18437   PerfEventConfig(const PerfEventConfig&);
18438   PerfEventConfig& operator=(const PerfEventConfig&);
18439   bool operator==(const PerfEventConfig&) const;
operator !=(const PerfEventConfig & other) const18440   bool operator!=(const PerfEventConfig& other) const { return !(*this == other); }
18441 
18442   bool ParseFromArray(const void*, size_t) override;
18443   std::string SerializeAsString() const override;
18444   std::vector<uint8_t> SerializeAsArray() const override;
18445   void Serialize(::protozero::Message*) const;
18446 
has_timebase() const18447   bool has_timebase() const { return _has_field_[15]; }
timebase() const18448   const PerfEvents_Timebase& timebase() const { return *timebase_; }
mutable_timebase()18449   PerfEvents_Timebase* mutable_timebase() { _has_field_.set(15); return timebase_.get(); }
18450 
has_callstack_sampling() const18451   bool has_callstack_sampling() const { return _has_field_[16]; }
callstack_sampling() const18452   const PerfEventConfig_CallstackSampling& callstack_sampling() const { return *callstack_sampling_; }
mutable_callstack_sampling()18453   PerfEventConfig_CallstackSampling* mutable_callstack_sampling() { _has_field_.set(16); return callstack_sampling_.get(); }
18454 
has_ring_buffer_read_period_ms() const18455   bool has_ring_buffer_read_period_ms() const { return _has_field_[8]; }
ring_buffer_read_period_ms() const18456   uint32_t ring_buffer_read_period_ms() const { return ring_buffer_read_period_ms_; }
set_ring_buffer_read_period_ms(uint32_t value)18457   void set_ring_buffer_read_period_ms(uint32_t value) { ring_buffer_read_period_ms_ = value; _has_field_.set(8); }
18458 
has_ring_buffer_pages() const18459   bool has_ring_buffer_pages() const { return _has_field_[3]; }
ring_buffer_pages() const18460   uint32_t ring_buffer_pages() const { return ring_buffer_pages_; }
set_ring_buffer_pages(uint32_t value)18461   void set_ring_buffer_pages(uint32_t value) { ring_buffer_pages_ = value; _has_field_.set(3); }
18462 
has_max_enqueued_footprint_kb() const18463   bool has_max_enqueued_footprint_kb() const { return _has_field_[17]; }
max_enqueued_footprint_kb() const18464   uint64_t max_enqueued_footprint_kb() const { return max_enqueued_footprint_kb_; }
set_max_enqueued_footprint_kb(uint64_t value)18465   void set_max_enqueued_footprint_kb(uint64_t value) { max_enqueued_footprint_kb_ = value; _has_field_.set(17); }
18466 
has_max_daemon_memory_kb() const18467   bool has_max_daemon_memory_kb() const { return _has_field_[13]; }
max_daemon_memory_kb() const18468   uint32_t max_daemon_memory_kb() const { return max_daemon_memory_kb_; }
set_max_daemon_memory_kb(uint32_t value)18469   void set_max_daemon_memory_kb(uint32_t value) { max_daemon_memory_kb_ = value; _has_field_.set(13); }
18470 
has_remote_descriptor_timeout_ms() const18471   bool has_remote_descriptor_timeout_ms() const { return _has_field_[9]; }
remote_descriptor_timeout_ms() const18472   uint32_t remote_descriptor_timeout_ms() const { return remote_descriptor_timeout_ms_; }
set_remote_descriptor_timeout_ms(uint32_t value)18473   void set_remote_descriptor_timeout_ms(uint32_t value) { remote_descriptor_timeout_ms_ = value; _has_field_.set(9); }
18474 
has_unwind_state_clear_period_ms() const18475   bool has_unwind_state_clear_period_ms() const { return _has_field_[10]; }
unwind_state_clear_period_ms() const18476   uint32_t unwind_state_clear_period_ms() const { return unwind_state_clear_period_ms_; }
set_unwind_state_clear_period_ms(uint32_t value)18477   void set_unwind_state_clear_period_ms(uint32_t value) { unwind_state_clear_period_ms_ = value; _has_field_.set(10); }
18478 
has_all_cpus() const18479   bool has_all_cpus() const { return _has_field_[1]; }
all_cpus() const18480   bool all_cpus() const { return all_cpus_; }
set_all_cpus(bool value)18481   void set_all_cpus(bool value) { all_cpus_ = value; _has_field_.set(1); }
18482 
has_sampling_frequency() const18483   bool has_sampling_frequency() const { return _has_field_[2]; }
sampling_frequency() const18484   uint32_t sampling_frequency() const { return sampling_frequency_; }
set_sampling_frequency(uint32_t value)18485   void set_sampling_frequency(uint32_t value) { sampling_frequency_ = value; _has_field_.set(2); }
18486 
has_kernel_frames() const18487   bool has_kernel_frames() const { return _has_field_[12]; }
kernel_frames() const18488   bool kernel_frames() const { return kernel_frames_; }
set_kernel_frames(bool value)18489   void set_kernel_frames(bool value) { kernel_frames_ = value; _has_field_.set(12); }
18490 
target_pid() const18491   const std::vector<int32_t>& target_pid() const { return target_pid_; }
mutable_target_pid()18492   std::vector<int32_t>* mutable_target_pid() { return &target_pid_; }
target_pid_size() const18493   int target_pid_size() const { return static_cast<int>(target_pid_.size()); }
clear_target_pid()18494   void clear_target_pid() { target_pid_.clear(); }
add_target_pid(int32_t value)18495   void add_target_pid(int32_t value) { target_pid_.emplace_back(value); }
add_target_pid()18496   int32_t* add_target_pid() { target_pid_.emplace_back(); return &target_pid_.back(); }
18497 
target_cmdline() const18498   const std::vector<std::string>& target_cmdline() const { return target_cmdline_; }
mutable_target_cmdline()18499   std::vector<std::string>* mutable_target_cmdline() { return &target_cmdline_; }
target_cmdline_size() const18500   int target_cmdline_size() const { return static_cast<int>(target_cmdline_.size()); }
clear_target_cmdline()18501   void clear_target_cmdline() { target_cmdline_.clear(); }
add_target_cmdline(std::string value)18502   void add_target_cmdline(std::string value) { target_cmdline_.emplace_back(value); }
add_target_cmdline()18503   std::string* add_target_cmdline() { target_cmdline_.emplace_back(); return &target_cmdline_.back(); }
18504 
target_installed_by() const18505   const std::vector<std::string>& target_installed_by() const { return target_installed_by_; }
mutable_target_installed_by()18506   std::vector<std::string>* mutable_target_installed_by() { return &target_installed_by_; }
target_installed_by_size() const18507   int target_installed_by_size() const { return static_cast<int>(target_installed_by_.size()); }
clear_target_installed_by()18508   void clear_target_installed_by() { target_installed_by_.clear(); }
add_target_installed_by(std::string value)18509   void add_target_installed_by(std::string value) { target_installed_by_.emplace_back(value); }
add_target_installed_by()18510   std::string* add_target_installed_by() { target_installed_by_.emplace_back(); return &target_installed_by_.back(); }
18511 
exclude_pid() const18512   const std::vector<int32_t>& exclude_pid() const { return exclude_pid_; }
mutable_exclude_pid()18513   std::vector<int32_t>* mutable_exclude_pid() { return &exclude_pid_; }
exclude_pid_size() const18514   int exclude_pid_size() const { return static_cast<int>(exclude_pid_.size()); }
clear_exclude_pid()18515   void clear_exclude_pid() { exclude_pid_.clear(); }
add_exclude_pid(int32_t value)18516   void add_exclude_pid(int32_t value) { exclude_pid_.emplace_back(value); }
add_exclude_pid()18517   int32_t* add_exclude_pid() { exclude_pid_.emplace_back(); return &exclude_pid_.back(); }
18518 
exclude_cmdline() const18519   const std::vector<std::string>& exclude_cmdline() const { return exclude_cmdline_; }
mutable_exclude_cmdline()18520   std::vector<std::string>* mutable_exclude_cmdline() { return &exclude_cmdline_; }
exclude_cmdline_size() const18521   int exclude_cmdline_size() const { return static_cast<int>(exclude_cmdline_.size()); }
clear_exclude_cmdline()18522   void clear_exclude_cmdline() { exclude_cmdline_.clear(); }
add_exclude_cmdline(std::string value)18523   void add_exclude_cmdline(std::string value) { exclude_cmdline_.emplace_back(value); }
add_exclude_cmdline()18524   std::string* add_exclude_cmdline() { exclude_cmdline_.emplace_back(); return &exclude_cmdline_.back(); }
18525 
has_additional_cmdline_count() const18526   bool has_additional_cmdline_count() const { return _has_field_[11]; }
additional_cmdline_count() const18527   uint32_t additional_cmdline_count() const { return additional_cmdline_count_; }
set_additional_cmdline_count(uint32_t value)18528   void set_additional_cmdline_count(uint32_t value) { additional_cmdline_count_ = value; _has_field_.set(11); }
18529 
18530  private:
18531   ::protozero::CopyablePtr<PerfEvents_Timebase> timebase_;
18532   ::protozero::CopyablePtr<PerfEventConfig_CallstackSampling> callstack_sampling_;
18533   uint32_t ring_buffer_read_period_ms_{};
18534   uint32_t ring_buffer_pages_{};
18535   uint64_t max_enqueued_footprint_kb_{};
18536   uint32_t max_daemon_memory_kb_{};
18537   uint32_t remote_descriptor_timeout_ms_{};
18538   uint32_t unwind_state_clear_period_ms_{};
18539   bool all_cpus_{};
18540   uint32_t sampling_frequency_{};
18541   bool kernel_frames_{};
18542   std::vector<int32_t> target_pid_;
18543   std::vector<std::string> target_cmdline_;
18544   std::vector<std::string> target_installed_by_;
18545   std::vector<int32_t> exclude_pid_;
18546   std::vector<std::string> exclude_cmdline_;
18547   uint32_t additional_cmdline_count_{};
18548 
18549   // Allows to preserve unknown protobuf fields for compatibility
18550   // with future versions of .proto files.
18551   std::string unknown_fields_;
18552 
18553   std::bitset<19> _has_field_{};
18554 };
18555 
18556 
18557 class PERFETTO_EXPORT PerfEventConfig_CallstackSampling : public ::protozero::CppMessageObj {
18558  public:
18559   enum FieldNumbers {
18560     kScopeFieldNumber = 1,
18561     kKernelFramesFieldNumber = 2,
18562   };
18563 
18564   PerfEventConfig_CallstackSampling();
18565   ~PerfEventConfig_CallstackSampling() override;
18566   PerfEventConfig_CallstackSampling(PerfEventConfig_CallstackSampling&&) noexcept;
18567   PerfEventConfig_CallstackSampling& operator=(PerfEventConfig_CallstackSampling&&);
18568   PerfEventConfig_CallstackSampling(const PerfEventConfig_CallstackSampling&);
18569   PerfEventConfig_CallstackSampling& operator=(const PerfEventConfig_CallstackSampling&);
18570   bool operator==(const PerfEventConfig_CallstackSampling&) const;
operator !=(const PerfEventConfig_CallstackSampling & other) const18571   bool operator!=(const PerfEventConfig_CallstackSampling& other) const { return !(*this == other); }
18572 
18573   bool ParseFromArray(const void*, size_t) override;
18574   std::string SerializeAsString() const override;
18575   std::vector<uint8_t> SerializeAsArray() const override;
18576   void Serialize(::protozero::Message*) const;
18577 
has_scope() const18578   bool has_scope() const { return _has_field_[1]; }
scope() const18579   const PerfEventConfig_Scope& scope() const { return *scope_; }
mutable_scope()18580   PerfEventConfig_Scope* mutable_scope() { _has_field_.set(1); return scope_.get(); }
18581 
has_kernel_frames() const18582   bool has_kernel_frames() const { return _has_field_[2]; }
kernel_frames() const18583   bool kernel_frames() const { return kernel_frames_; }
set_kernel_frames(bool value)18584   void set_kernel_frames(bool value) { kernel_frames_ = value; _has_field_.set(2); }
18585 
18586  private:
18587   ::protozero::CopyablePtr<PerfEventConfig_Scope> scope_;
18588   bool kernel_frames_{};
18589 
18590   // Allows to preserve unknown protobuf fields for compatibility
18591   // with future versions of .proto files.
18592   std::string unknown_fields_;
18593 
18594   std::bitset<3> _has_field_{};
18595 };
18596 
18597 
18598 class PERFETTO_EXPORT PerfEventConfig_Scope : public ::protozero::CppMessageObj {
18599  public:
18600   enum FieldNumbers {
18601     kTargetPidFieldNumber = 1,
18602     kTargetCmdlineFieldNumber = 2,
18603     kExcludePidFieldNumber = 3,
18604     kExcludeCmdlineFieldNumber = 4,
18605     kAdditionalCmdlineCountFieldNumber = 5,
18606   };
18607 
18608   PerfEventConfig_Scope();
18609   ~PerfEventConfig_Scope() override;
18610   PerfEventConfig_Scope(PerfEventConfig_Scope&&) noexcept;
18611   PerfEventConfig_Scope& operator=(PerfEventConfig_Scope&&);
18612   PerfEventConfig_Scope(const PerfEventConfig_Scope&);
18613   PerfEventConfig_Scope& operator=(const PerfEventConfig_Scope&);
18614   bool operator==(const PerfEventConfig_Scope&) const;
operator !=(const PerfEventConfig_Scope & other) const18615   bool operator!=(const PerfEventConfig_Scope& other) const { return !(*this == other); }
18616 
18617   bool ParseFromArray(const void*, size_t) override;
18618   std::string SerializeAsString() const override;
18619   std::vector<uint8_t> SerializeAsArray() const override;
18620   void Serialize(::protozero::Message*) const;
18621 
target_pid() const18622   const std::vector<int32_t>& target_pid() const { return target_pid_; }
mutable_target_pid()18623   std::vector<int32_t>* mutable_target_pid() { return &target_pid_; }
target_pid_size() const18624   int target_pid_size() const { return static_cast<int>(target_pid_.size()); }
clear_target_pid()18625   void clear_target_pid() { target_pid_.clear(); }
add_target_pid(int32_t value)18626   void add_target_pid(int32_t value) { target_pid_.emplace_back(value); }
add_target_pid()18627   int32_t* add_target_pid() { target_pid_.emplace_back(); return &target_pid_.back(); }
18628 
target_cmdline() const18629   const std::vector<std::string>& target_cmdline() const { return target_cmdline_; }
mutable_target_cmdline()18630   std::vector<std::string>* mutable_target_cmdline() { return &target_cmdline_; }
target_cmdline_size() const18631   int target_cmdline_size() const { return static_cast<int>(target_cmdline_.size()); }
clear_target_cmdline()18632   void clear_target_cmdline() { target_cmdline_.clear(); }
add_target_cmdline(std::string value)18633   void add_target_cmdline(std::string value) { target_cmdline_.emplace_back(value); }
add_target_cmdline()18634   std::string* add_target_cmdline() { target_cmdline_.emplace_back(); return &target_cmdline_.back(); }
18635 
exclude_pid() const18636   const std::vector<int32_t>& exclude_pid() const { return exclude_pid_; }
mutable_exclude_pid()18637   std::vector<int32_t>* mutable_exclude_pid() { return &exclude_pid_; }
exclude_pid_size() const18638   int exclude_pid_size() const { return static_cast<int>(exclude_pid_.size()); }
clear_exclude_pid()18639   void clear_exclude_pid() { exclude_pid_.clear(); }
add_exclude_pid(int32_t value)18640   void add_exclude_pid(int32_t value) { exclude_pid_.emplace_back(value); }
add_exclude_pid()18641   int32_t* add_exclude_pid() { exclude_pid_.emplace_back(); return &exclude_pid_.back(); }
18642 
exclude_cmdline() const18643   const std::vector<std::string>& exclude_cmdline() const { return exclude_cmdline_; }
mutable_exclude_cmdline()18644   std::vector<std::string>* mutable_exclude_cmdline() { return &exclude_cmdline_; }
exclude_cmdline_size() const18645   int exclude_cmdline_size() const { return static_cast<int>(exclude_cmdline_.size()); }
clear_exclude_cmdline()18646   void clear_exclude_cmdline() { exclude_cmdline_.clear(); }
add_exclude_cmdline(std::string value)18647   void add_exclude_cmdline(std::string value) { exclude_cmdline_.emplace_back(value); }
add_exclude_cmdline()18648   std::string* add_exclude_cmdline() { exclude_cmdline_.emplace_back(); return &exclude_cmdline_.back(); }
18649 
has_additional_cmdline_count() const18650   bool has_additional_cmdline_count() const { return _has_field_[5]; }
additional_cmdline_count() const18651   uint32_t additional_cmdline_count() const { return additional_cmdline_count_; }
set_additional_cmdline_count(uint32_t value)18652   void set_additional_cmdline_count(uint32_t value) { additional_cmdline_count_ = value; _has_field_.set(5); }
18653 
18654  private:
18655   std::vector<int32_t> target_pid_;
18656   std::vector<std::string> target_cmdline_;
18657   std::vector<int32_t> exclude_pid_;
18658   std::vector<std::string> exclude_cmdline_;
18659   uint32_t additional_cmdline_count_{};
18660 
18661   // Allows to preserve unknown protobuf fields for compatibility
18662   // with future versions of .proto files.
18663   std::string unknown_fields_;
18664 
18665   std::bitset<6> _has_field_{};
18666 };
18667 
18668 }  // namespace perfetto
18669 }  // namespace protos
18670 }  // namespace gen
18671 
18672 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_PERF_EVENT_CONFIG_PROTO_CPP_H_
18673 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
18674 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
18675 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
18676 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
18677 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
18678 #if defined(__GNUC__) || defined(__clang__)
18679 #pragma GCC diagnostic push
18680 #pragma GCC diagnostic ignored "-Wfloat-equal"
18681 #endif
18682 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/perf_event_config.gen.h"
18683 // gen_amalgamated expanded: #include "protos/perfetto/common/perf_events.gen.h"
18684 
18685 namespace perfetto {
18686 namespace protos {
18687 namespace gen {
18688 
18689 PerfEventConfig::PerfEventConfig() = default;
18690 PerfEventConfig::~PerfEventConfig() = default;
18691 PerfEventConfig::PerfEventConfig(const PerfEventConfig&) = default;
18692 PerfEventConfig& PerfEventConfig::operator=(const PerfEventConfig&) = default;
18693 PerfEventConfig::PerfEventConfig(PerfEventConfig&&) noexcept = default;
18694 PerfEventConfig& PerfEventConfig::operator=(PerfEventConfig&&) = default;
18695 
operator ==(const PerfEventConfig & other) const18696 bool PerfEventConfig::operator==(const PerfEventConfig& other) const {
18697   return unknown_fields_ == other.unknown_fields_
18698    && timebase_ == other.timebase_
18699    && callstack_sampling_ == other.callstack_sampling_
18700    && ring_buffer_read_period_ms_ == other.ring_buffer_read_period_ms_
18701    && ring_buffer_pages_ == other.ring_buffer_pages_
18702    && max_enqueued_footprint_kb_ == other.max_enqueued_footprint_kb_
18703    && max_daemon_memory_kb_ == other.max_daemon_memory_kb_
18704    && remote_descriptor_timeout_ms_ == other.remote_descriptor_timeout_ms_
18705    && unwind_state_clear_period_ms_ == other.unwind_state_clear_period_ms_
18706    && all_cpus_ == other.all_cpus_
18707    && sampling_frequency_ == other.sampling_frequency_
18708    && kernel_frames_ == other.kernel_frames_
18709    && target_pid_ == other.target_pid_
18710    && target_cmdline_ == other.target_cmdline_
18711    && target_installed_by_ == other.target_installed_by_
18712    && exclude_pid_ == other.exclude_pid_
18713    && exclude_cmdline_ == other.exclude_cmdline_
18714    && additional_cmdline_count_ == other.additional_cmdline_count_;
18715 }
18716 
ParseFromArray(const void * raw,size_t size)18717 bool PerfEventConfig::ParseFromArray(const void* raw, size_t size) {
18718   target_pid_.clear();
18719   target_cmdline_.clear();
18720   target_installed_by_.clear();
18721   exclude_pid_.clear();
18722   exclude_cmdline_.clear();
18723   unknown_fields_.clear();
18724   bool packed_error = false;
18725 
18726   ::protozero::ProtoDecoder dec(raw, size);
18727   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
18728     if (field.id() < _has_field_.size()) {
18729       _has_field_.set(field.id());
18730     }
18731     switch (field.id()) {
18732       case 15 /* timebase */:
18733         (*timebase_).ParseFromArray(field.data(), field.size());
18734         break;
18735       case 16 /* callstack_sampling */:
18736         (*callstack_sampling_).ParseFromArray(field.data(), field.size());
18737         break;
18738       case 8 /* ring_buffer_read_period_ms */:
18739         field.get(&ring_buffer_read_period_ms_);
18740         break;
18741       case 3 /* ring_buffer_pages */:
18742         field.get(&ring_buffer_pages_);
18743         break;
18744       case 17 /* max_enqueued_footprint_kb */:
18745         field.get(&max_enqueued_footprint_kb_);
18746         break;
18747       case 13 /* max_daemon_memory_kb */:
18748         field.get(&max_daemon_memory_kb_);
18749         break;
18750       case 9 /* remote_descriptor_timeout_ms */:
18751         field.get(&remote_descriptor_timeout_ms_);
18752         break;
18753       case 10 /* unwind_state_clear_period_ms */:
18754         field.get(&unwind_state_clear_period_ms_);
18755         break;
18756       case 1 /* all_cpus */:
18757         field.get(&all_cpus_);
18758         break;
18759       case 2 /* sampling_frequency */:
18760         field.get(&sampling_frequency_);
18761         break;
18762       case 12 /* kernel_frames */:
18763         field.get(&kernel_frames_);
18764         break;
18765       case 4 /* target_pid */:
18766         target_pid_.emplace_back();
18767         field.get(&target_pid_.back());
18768         break;
18769       case 5 /* target_cmdline */:
18770         target_cmdline_.emplace_back();
18771         field.get(&target_cmdline_.back());
18772         break;
18773       case 18 /* target_installed_by */:
18774         target_installed_by_.emplace_back();
18775         field.get(&target_installed_by_.back());
18776         break;
18777       case 6 /* exclude_pid */:
18778         exclude_pid_.emplace_back();
18779         field.get(&exclude_pid_.back());
18780         break;
18781       case 7 /* exclude_cmdline */:
18782         exclude_cmdline_.emplace_back();
18783         field.get(&exclude_cmdline_.back());
18784         break;
18785       case 11 /* additional_cmdline_count */:
18786         field.get(&additional_cmdline_count_);
18787         break;
18788       default:
18789         field.SerializeAndAppendTo(&unknown_fields_);
18790         break;
18791     }
18792   }
18793   return !packed_error && !dec.bytes_left();
18794 }
18795 
SerializeAsString() const18796 std::string PerfEventConfig::SerializeAsString() const {
18797   ::protozero::HeapBuffered<::protozero::Message> msg;
18798   Serialize(msg.get());
18799   return msg.SerializeAsString();
18800 }
18801 
SerializeAsArray() const18802 std::vector<uint8_t> PerfEventConfig::SerializeAsArray() const {
18803   ::protozero::HeapBuffered<::protozero::Message> msg;
18804   Serialize(msg.get());
18805   return msg.SerializeAsArray();
18806 }
18807 
Serialize(::protozero::Message * msg) const18808 void PerfEventConfig::Serialize(::protozero::Message* msg) const {
18809   // Field 15: timebase
18810   if (_has_field_[15]) {
18811     (*timebase_).Serialize(msg->BeginNestedMessage<::protozero::Message>(15));
18812   }
18813 
18814   // Field 16: callstack_sampling
18815   if (_has_field_[16]) {
18816     (*callstack_sampling_).Serialize(msg->BeginNestedMessage<::protozero::Message>(16));
18817   }
18818 
18819   // Field 8: ring_buffer_read_period_ms
18820   if (_has_field_[8]) {
18821     msg->AppendVarInt(8, ring_buffer_read_period_ms_);
18822   }
18823 
18824   // Field 3: ring_buffer_pages
18825   if (_has_field_[3]) {
18826     msg->AppendVarInt(3, ring_buffer_pages_);
18827   }
18828 
18829   // Field 17: max_enqueued_footprint_kb
18830   if (_has_field_[17]) {
18831     msg->AppendVarInt(17, max_enqueued_footprint_kb_);
18832   }
18833 
18834   // Field 13: max_daemon_memory_kb
18835   if (_has_field_[13]) {
18836     msg->AppendVarInt(13, max_daemon_memory_kb_);
18837   }
18838 
18839   // Field 9: remote_descriptor_timeout_ms
18840   if (_has_field_[9]) {
18841     msg->AppendVarInt(9, remote_descriptor_timeout_ms_);
18842   }
18843 
18844   // Field 10: unwind_state_clear_period_ms
18845   if (_has_field_[10]) {
18846     msg->AppendVarInt(10, unwind_state_clear_period_ms_);
18847   }
18848 
18849   // Field 1: all_cpus
18850   if (_has_field_[1]) {
18851     msg->AppendTinyVarInt(1, all_cpus_);
18852   }
18853 
18854   // Field 2: sampling_frequency
18855   if (_has_field_[2]) {
18856     msg->AppendVarInt(2, sampling_frequency_);
18857   }
18858 
18859   // Field 12: kernel_frames
18860   if (_has_field_[12]) {
18861     msg->AppendTinyVarInt(12, kernel_frames_);
18862   }
18863 
18864   // Field 4: target_pid
18865   for (auto& it : target_pid_) {
18866     msg->AppendVarInt(4, it);
18867   }
18868 
18869   // Field 5: target_cmdline
18870   for (auto& it : target_cmdline_) {
18871     msg->AppendString(5, it);
18872   }
18873 
18874   // Field 18: target_installed_by
18875   for (auto& it : target_installed_by_) {
18876     msg->AppendString(18, it);
18877   }
18878 
18879   // Field 6: exclude_pid
18880   for (auto& it : exclude_pid_) {
18881     msg->AppendVarInt(6, it);
18882   }
18883 
18884   // Field 7: exclude_cmdline
18885   for (auto& it : exclude_cmdline_) {
18886     msg->AppendString(7, it);
18887   }
18888 
18889   // Field 11: additional_cmdline_count
18890   if (_has_field_[11]) {
18891     msg->AppendVarInt(11, additional_cmdline_count_);
18892   }
18893 
18894   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
18895 }
18896 
18897 
18898 PerfEventConfig_CallstackSampling::PerfEventConfig_CallstackSampling() = default;
18899 PerfEventConfig_CallstackSampling::~PerfEventConfig_CallstackSampling() = default;
18900 PerfEventConfig_CallstackSampling::PerfEventConfig_CallstackSampling(const PerfEventConfig_CallstackSampling&) = default;
18901 PerfEventConfig_CallstackSampling& PerfEventConfig_CallstackSampling::operator=(const PerfEventConfig_CallstackSampling&) = default;
18902 PerfEventConfig_CallstackSampling::PerfEventConfig_CallstackSampling(PerfEventConfig_CallstackSampling&&) noexcept = default;
18903 PerfEventConfig_CallstackSampling& PerfEventConfig_CallstackSampling::operator=(PerfEventConfig_CallstackSampling&&) = default;
18904 
operator ==(const PerfEventConfig_CallstackSampling & other) const18905 bool PerfEventConfig_CallstackSampling::operator==(const PerfEventConfig_CallstackSampling& other) const {
18906   return unknown_fields_ == other.unknown_fields_
18907    && scope_ == other.scope_
18908    && kernel_frames_ == other.kernel_frames_;
18909 }
18910 
ParseFromArray(const void * raw,size_t size)18911 bool PerfEventConfig_CallstackSampling::ParseFromArray(const void* raw, size_t size) {
18912   unknown_fields_.clear();
18913   bool packed_error = false;
18914 
18915   ::protozero::ProtoDecoder dec(raw, size);
18916   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
18917     if (field.id() < _has_field_.size()) {
18918       _has_field_.set(field.id());
18919     }
18920     switch (field.id()) {
18921       case 1 /* scope */:
18922         (*scope_).ParseFromArray(field.data(), field.size());
18923         break;
18924       case 2 /* kernel_frames */:
18925         field.get(&kernel_frames_);
18926         break;
18927       default:
18928         field.SerializeAndAppendTo(&unknown_fields_);
18929         break;
18930     }
18931   }
18932   return !packed_error && !dec.bytes_left();
18933 }
18934 
SerializeAsString() const18935 std::string PerfEventConfig_CallstackSampling::SerializeAsString() const {
18936   ::protozero::HeapBuffered<::protozero::Message> msg;
18937   Serialize(msg.get());
18938   return msg.SerializeAsString();
18939 }
18940 
SerializeAsArray() const18941 std::vector<uint8_t> PerfEventConfig_CallstackSampling::SerializeAsArray() const {
18942   ::protozero::HeapBuffered<::protozero::Message> msg;
18943   Serialize(msg.get());
18944   return msg.SerializeAsArray();
18945 }
18946 
Serialize(::protozero::Message * msg) const18947 void PerfEventConfig_CallstackSampling::Serialize(::protozero::Message* msg) const {
18948   // Field 1: scope
18949   if (_has_field_[1]) {
18950     (*scope_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
18951   }
18952 
18953   // Field 2: kernel_frames
18954   if (_has_field_[2]) {
18955     msg->AppendTinyVarInt(2, kernel_frames_);
18956   }
18957 
18958   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
18959 }
18960 
18961 
18962 PerfEventConfig_Scope::PerfEventConfig_Scope() = default;
18963 PerfEventConfig_Scope::~PerfEventConfig_Scope() = default;
18964 PerfEventConfig_Scope::PerfEventConfig_Scope(const PerfEventConfig_Scope&) = default;
18965 PerfEventConfig_Scope& PerfEventConfig_Scope::operator=(const PerfEventConfig_Scope&) = default;
18966 PerfEventConfig_Scope::PerfEventConfig_Scope(PerfEventConfig_Scope&&) noexcept = default;
18967 PerfEventConfig_Scope& PerfEventConfig_Scope::operator=(PerfEventConfig_Scope&&) = default;
18968 
operator ==(const PerfEventConfig_Scope & other) const18969 bool PerfEventConfig_Scope::operator==(const PerfEventConfig_Scope& other) const {
18970   return unknown_fields_ == other.unknown_fields_
18971    && target_pid_ == other.target_pid_
18972    && target_cmdline_ == other.target_cmdline_
18973    && exclude_pid_ == other.exclude_pid_
18974    && exclude_cmdline_ == other.exclude_cmdline_
18975    && additional_cmdline_count_ == other.additional_cmdline_count_;
18976 }
18977 
ParseFromArray(const void * raw,size_t size)18978 bool PerfEventConfig_Scope::ParseFromArray(const void* raw, size_t size) {
18979   target_pid_.clear();
18980   target_cmdline_.clear();
18981   exclude_pid_.clear();
18982   exclude_cmdline_.clear();
18983   unknown_fields_.clear();
18984   bool packed_error = false;
18985 
18986   ::protozero::ProtoDecoder dec(raw, size);
18987   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
18988     if (field.id() < _has_field_.size()) {
18989       _has_field_.set(field.id());
18990     }
18991     switch (field.id()) {
18992       case 1 /* target_pid */:
18993         target_pid_.emplace_back();
18994         field.get(&target_pid_.back());
18995         break;
18996       case 2 /* target_cmdline */:
18997         target_cmdline_.emplace_back();
18998         field.get(&target_cmdline_.back());
18999         break;
19000       case 3 /* exclude_pid */:
19001         exclude_pid_.emplace_back();
19002         field.get(&exclude_pid_.back());
19003         break;
19004       case 4 /* exclude_cmdline */:
19005         exclude_cmdline_.emplace_back();
19006         field.get(&exclude_cmdline_.back());
19007         break;
19008       case 5 /* additional_cmdline_count */:
19009         field.get(&additional_cmdline_count_);
19010         break;
19011       default:
19012         field.SerializeAndAppendTo(&unknown_fields_);
19013         break;
19014     }
19015   }
19016   return !packed_error && !dec.bytes_left();
19017 }
19018 
SerializeAsString() const19019 std::string PerfEventConfig_Scope::SerializeAsString() const {
19020   ::protozero::HeapBuffered<::protozero::Message> msg;
19021   Serialize(msg.get());
19022   return msg.SerializeAsString();
19023 }
19024 
SerializeAsArray() const19025 std::vector<uint8_t> PerfEventConfig_Scope::SerializeAsArray() const {
19026   ::protozero::HeapBuffered<::protozero::Message> msg;
19027   Serialize(msg.get());
19028   return msg.SerializeAsArray();
19029 }
19030 
Serialize(::protozero::Message * msg) const19031 void PerfEventConfig_Scope::Serialize(::protozero::Message* msg) const {
19032   // Field 1: target_pid
19033   for (auto& it : target_pid_) {
19034     msg->AppendVarInt(1, it);
19035   }
19036 
19037   // Field 2: target_cmdline
19038   for (auto& it : target_cmdline_) {
19039     msg->AppendString(2, it);
19040   }
19041 
19042   // Field 3: exclude_pid
19043   for (auto& it : exclude_pid_) {
19044     msg->AppendVarInt(3, it);
19045   }
19046 
19047   // Field 4: exclude_cmdline
19048   for (auto& it : exclude_cmdline_) {
19049     msg->AppendString(4, it);
19050   }
19051 
19052   // Field 5: additional_cmdline_count
19053   if (_has_field_[5]) {
19054     msg->AppendVarInt(5, additional_cmdline_count_);
19055   }
19056 
19057   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
19058 }
19059 
19060 }  // namespace perfetto
19061 }  // namespace protos
19062 }  // namespace gen
19063 #if defined(__GNUC__) || defined(__clang__)
19064 #pragma GCC diagnostic pop
19065 #endif
19066 // gen_amalgamated begin source: gen/protos/perfetto/config/sys_stats/sys_stats_config.gen.cc
19067 // gen_amalgamated begin header: gen/protos/perfetto/config/sys_stats/sys_stats_config.gen.h
19068 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
19069 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_SYS_STATS_SYS_STATS_CONFIG_PROTO_CPP_H_
19070 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_SYS_STATS_SYS_STATS_CONFIG_PROTO_CPP_H_
19071 
19072 #include <stdint.h>
19073 #include <bitset>
19074 #include <vector>
19075 #include <string>
19076 #include <type_traits>
19077 
19078 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
19079 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
19080 // gen_amalgamated expanded: #include "perfetto/base/export.h"
19081 
19082 namespace perfetto {
19083 namespace protos {
19084 namespace gen {
19085 class SysStatsConfig;
19086 enum SysStatsConfig_StatCounters : int;
19087 enum MeminfoCounters : int;
19088 enum VmstatCounters : int;
19089 }  // namespace perfetto
19090 }  // namespace protos
19091 }  // namespace gen
19092 
19093 namespace protozero {
19094 class Message;
19095 }  // namespace protozero
19096 
19097 namespace perfetto {
19098 namespace protos {
19099 namespace gen {
19100 enum SysStatsConfig_StatCounters : int {
19101   SysStatsConfig_StatCounters_STAT_UNSPECIFIED = 0,
19102   SysStatsConfig_StatCounters_STAT_CPU_TIMES = 1,
19103   SysStatsConfig_StatCounters_STAT_IRQ_COUNTS = 2,
19104   SysStatsConfig_StatCounters_STAT_SOFTIRQ_COUNTS = 3,
19105   SysStatsConfig_StatCounters_STAT_FORK_COUNT = 4,
19106 };
19107 
19108 class PERFETTO_EXPORT SysStatsConfig : public ::protozero::CppMessageObj {
19109  public:
19110   using StatCounters = SysStatsConfig_StatCounters;
19111   static constexpr auto STAT_UNSPECIFIED = SysStatsConfig_StatCounters_STAT_UNSPECIFIED;
19112   static constexpr auto STAT_CPU_TIMES = SysStatsConfig_StatCounters_STAT_CPU_TIMES;
19113   static constexpr auto STAT_IRQ_COUNTS = SysStatsConfig_StatCounters_STAT_IRQ_COUNTS;
19114   static constexpr auto STAT_SOFTIRQ_COUNTS = SysStatsConfig_StatCounters_STAT_SOFTIRQ_COUNTS;
19115   static constexpr auto STAT_FORK_COUNT = SysStatsConfig_StatCounters_STAT_FORK_COUNT;
19116   static constexpr auto StatCounters_MIN = SysStatsConfig_StatCounters_STAT_UNSPECIFIED;
19117   static constexpr auto StatCounters_MAX = SysStatsConfig_StatCounters_STAT_FORK_COUNT;
19118   enum FieldNumbers {
19119     kMeminfoPeriodMsFieldNumber = 1,
19120     kMeminfoCountersFieldNumber = 2,
19121     kVmstatPeriodMsFieldNumber = 3,
19122     kVmstatCountersFieldNumber = 4,
19123     kStatPeriodMsFieldNumber = 5,
19124     kStatCountersFieldNumber = 6,
19125     kDevfreqPeriodMsFieldNumber = 7,
19126   };
19127 
19128   SysStatsConfig();
19129   ~SysStatsConfig() override;
19130   SysStatsConfig(SysStatsConfig&&) noexcept;
19131   SysStatsConfig& operator=(SysStatsConfig&&);
19132   SysStatsConfig(const SysStatsConfig&);
19133   SysStatsConfig& operator=(const SysStatsConfig&);
19134   bool operator==(const SysStatsConfig&) const;
operator !=(const SysStatsConfig & other) const19135   bool operator!=(const SysStatsConfig& other) const { return !(*this == other); }
19136 
19137   bool ParseFromArray(const void*, size_t) override;
19138   std::string SerializeAsString() const override;
19139   std::vector<uint8_t> SerializeAsArray() const override;
19140   void Serialize(::protozero::Message*) const;
19141 
has_meminfo_period_ms() const19142   bool has_meminfo_period_ms() const { return _has_field_[1]; }
meminfo_period_ms() const19143   uint32_t meminfo_period_ms() const { return meminfo_period_ms_; }
set_meminfo_period_ms(uint32_t value)19144   void set_meminfo_period_ms(uint32_t value) { meminfo_period_ms_ = value; _has_field_.set(1); }
19145 
meminfo_counters() const19146   const std::vector<MeminfoCounters>& meminfo_counters() const { return meminfo_counters_; }
mutable_meminfo_counters()19147   std::vector<MeminfoCounters>* mutable_meminfo_counters() { return &meminfo_counters_; }
meminfo_counters_size() const19148   int meminfo_counters_size() const { return static_cast<int>(meminfo_counters_.size()); }
clear_meminfo_counters()19149   void clear_meminfo_counters() { meminfo_counters_.clear(); }
add_meminfo_counters(MeminfoCounters value)19150   void add_meminfo_counters(MeminfoCounters value) { meminfo_counters_.emplace_back(value); }
add_meminfo_counters()19151   MeminfoCounters* add_meminfo_counters() { meminfo_counters_.emplace_back(); return &meminfo_counters_.back(); }
19152 
has_vmstat_period_ms() const19153   bool has_vmstat_period_ms() const { return _has_field_[3]; }
vmstat_period_ms() const19154   uint32_t vmstat_period_ms() const { return vmstat_period_ms_; }
set_vmstat_period_ms(uint32_t value)19155   void set_vmstat_period_ms(uint32_t value) { vmstat_period_ms_ = value; _has_field_.set(3); }
19156 
vmstat_counters() const19157   const std::vector<VmstatCounters>& vmstat_counters() const { return vmstat_counters_; }
mutable_vmstat_counters()19158   std::vector<VmstatCounters>* mutable_vmstat_counters() { return &vmstat_counters_; }
vmstat_counters_size() const19159   int vmstat_counters_size() const { return static_cast<int>(vmstat_counters_.size()); }
clear_vmstat_counters()19160   void clear_vmstat_counters() { vmstat_counters_.clear(); }
add_vmstat_counters(VmstatCounters value)19161   void add_vmstat_counters(VmstatCounters value) { vmstat_counters_.emplace_back(value); }
add_vmstat_counters()19162   VmstatCounters* add_vmstat_counters() { vmstat_counters_.emplace_back(); return &vmstat_counters_.back(); }
19163 
has_stat_period_ms() const19164   bool has_stat_period_ms() const { return _has_field_[5]; }
stat_period_ms() const19165   uint32_t stat_period_ms() const { return stat_period_ms_; }
set_stat_period_ms(uint32_t value)19166   void set_stat_period_ms(uint32_t value) { stat_period_ms_ = value; _has_field_.set(5); }
19167 
stat_counters() const19168   const std::vector<SysStatsConfig_StatCounters>& stat_counters() const { return stat_counters_; }
mutable_stat_counters()19169   std::vector<SysStatsConfig_StatCounters>* mutable_stat_counters() { return &stat_counters_; }
stat_counters_size() const19170   int stat_counters_size() const { return static_cast<int>(stat_counters_.size()); }
clear_stat_counters()19171   void clear_stat_counters() { stat_counters_.clear(); }
add_stat_counters(SysStatsConfig_StatCounters value)19172   void add_stat_counters(SysStatsConfig_StatCounters value) { stat_counters_.emplace_back(value); }
add_stat_counters()19173   SysStatsConfig_StatCounters* add_stat_counters() { stat_counters_.emplace_back(); return &stat_counters_.back(); }
19174 
has_devfreq_period_ms() const19175   bool has_devfreq_period_ms() const { return _has_field_[7]; }
devfreq_period_ms() const19176   uint32_t devfreq_period_ms() const { return devfreq_period_ms_; }
set_devfreq_period_ms(uint32_t value)19177   void set_devfreq_period_ms(uint32_t value) { devfreq_period_ms_ = value; _has_field_.set(7); }
19178 
19179  private:
19180   uint32_t meminfo_period_ms_{};
19181   std::vector<MeminfoCounters> meminfo_counters_;
19182   uint32_t vmstat_period_ms_{};
19183   std::vector<VmstatCounters> vmstat_counters_;
19184   uint32_t stat_period_ms_{};
19185   std::vector<SysStatsConfig_StatCounters> stat_counters_;
19186   uint32_t devfreq_period_ms_{};
19187 
19188   // Allows to preserve unknown protobuf fields for compatibility
19189   // with future versions of .proto files.
19190   std::string unknown_fields_;
19191 
19192   std::bitset<8> _has_field_{};
19193 };
19194 
19195 }  // namespace perfetto
19196 }  // namespace protos
19197 }  // namespace gen
19198 
19199 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_SYS_STATS_SYS_STATS_CONFIG_PROTO_CPP_H_
19200 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
19201 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
19202 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
19203 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
19204 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
19205 #if defined(__GNUC__) || defined(__clang__)
19206 #pragma GCC diagnostic push
19207 #pragma GCC diagnostic ignored "-Wfloat-equal"
19208 #endif
19209 // gen_amalgamated expanded: #include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
19210 // gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
19211 
19212 namespace perfetto {
19213 namespace protos {
19214 namespace gen {
19215 
19216 SysStatsConfig::SysStatsConfig() = default;
19217 SysStatsConfig::~SysStatsConfig() = default;
19218 SysStatsConfig::SysStatsConfig(const SysStatsConfig&) = default;
19219 SysStatsConfig& SysStatsConfig::operator=(const SysStatsConfig&) = default;
19220 SysStatsConfig::SysStatsConfig(SysStatsConfig&&) noexcept = default;
19221 SysStatsConfig& SysStatsConfig::operator=(SysStatsConfig&&) = default;
19222 
operator ==(const SysStatsConfig & other) const19223 bool SysStatsConfig::operator==(const SysStatsConfig& other) const {
19224   return unknown_fields_ == other.unknown_fields_
19225    && meminfo_period_ms_ == other.meminfo_period_ms_
19226    && meminfo_counters_ == other.meminfo_counters_
19227    && vmstat_period_ms_ == other.vmstat_period_ms_
19228    && vmstat_counters_ == other.vmstat_counters_
19229    && stat_period_ms_ == other.stat_period_ms_
19230    && stat_counters_ == other.stat_counters_
19231    && devfreq_period_ms_ == other.devfreq_period_ms_;
19232 }
19233 
ParseFromArray(const void * raw,size_t size)19234 bool SysStatsConfig::ParseFromArray(const void* raw, size_t size) {
19235   meminfo_counters_.clear();
19236   vmstat_counters_.clear();
19237   stat_counters_.clear();
19238   unknown_fields_.clear();
19239   bool packed_error = false;
19240 
19241   ::protozero::ProtoDecoder dec(raw, size);
19242   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
19243     if (field.id() < _has_field_.size()) {
19244       _has_field_.set(field.id());
19245     }
19246     switch (field.id()) {
19247       case 1 /* meminfo_period_ms */:
19248         field.get(&meminfo_period_ms_);
19249         break;
19250       case 2 /* meminfo_counters */:
19251         meminfo_counters_.emplace_back();
19252         field.get(&meminfo_counters_.back());
19253         break;
19254       case 3 /* vmstat_period_ms */:
19255         field.get(&vmstat_period_ms_);
19256         break;
19257       case 4 /* vmstat_counters */:
19258         vmstat_counters_.emplace_back();
19259         field.get(&vmstat_counters_.back());
19260         break;
19261       case 5 /* stat_period_ms */:
19262         field.get(&stat_period_ms_);
19263         break;
19264       case 6 /* stat_counters */:
19265         stat_counters_.emplace_back();
19266         field.get(&stat_counters_.back());
19267         break;
19268       case 7 /* devfreq_period_ms */:
19269         field.get(&devfreq_period_ms_);
19270         break;
19271       default:
19272         field.SerializeAndAppendTo(&unknown_fields_);
19273         break;
19274     }
19275   }
19276   return !packed_error && !dec.bytes_left();
19277 }
19278 
SerializeAsString() const19279 std::string SysStatsConfig::SerializeAsString() const {
19280   ::protozero::HeapBuffered<::protozero::Message> msg;
19281   Serialize(msg.get());
19282   return msg.SerializeAsString();
19283 }
19284 
SerializeAsArray() const19285 std::vector<uint8_t> SysStatsConfig::SerializeAsArray() const {
19286   ::protozero::HeapBuffered<::protozero::Message> msg;
19287   Serialize(msg.get());
19288   return msg.SerializeAsArray();
19289 }
19290 
Serialize(::protozero::Message * msg) const19291 void SysStatsConfig::Serialize(::protozero::Message* msg) const {
19292   // Field 1: meminfo_period_ms
19293   if (_has_field_[1]) {
19294     msg->AppendVarInt(1, meminfo_period_ms_);
19295   }
19296 
19297   // Field 2: meminfo_counters
19298   for (auto& it : meminfo_counters_) {
19299     msg->AppendVarInt(2, it);
19300   }
19301 
19302   // Field 3: vmstat_period_ms
19303   if (_has_field_[3]) {
19304     msg->AppendVarInt(3, vmstat_period_ms_);
19305   }
19306 
19307   // Field 4: vmstat_counters
19308   for (auto& it : vmstat_counters_) {
19309     msg->AppendVarInt(4, it);
19310   }
19311 
19312   // Field 5: stat_period_ms
19313   if (_has_field_[5]) {
19314     msg->AppendVarInt(5, stat_period_ms_);
19315   }
19316 
19317   // Field 6: stat_counters
19318   for (auto& it : stat_counters_) {
19319     msg->AppendVarInt(6, it);
19320   }
19321 
19322   // Field 7: devfreq_period_ms
19323   if (_has_field_[7]) {
19324     msg->AppendVarInt(7, devfreq_period_ms_);
19325   }
19326 
19327   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
19328 }
19329 
19330 }  // namespace perfetto
19331 }  // namespace protos
19332 }  // namespace gen
19333 #if defined(__GNUC__) || defined(__clang__)
19334 #pragma GCC diagnostic pop
19335 #endif
19336 // gen_amalgamated begin source: gen/protos/perfetto/config/track_event/track_event_config.gen.cc
19337 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
19338 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
19339 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
19340 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
19341 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
19342 #if defined(__GNUC__) || defined(__clang__)
19343 #pragma GCC diagnostic push
19344 #pragma GCC diagnostic ignored "-Wfloat-equal"
19345 #endif
19346 // gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"
19347 
19348 namespace perfetto {
19349 namespace protos {
19350 namespace gen {
19351 
19352 TrackEventConfig::TrackEventConfig() = default;
19353 TrackEventConfig::~TrackEventConfig() = default;
19354 TrackEventConfig::TrackEventConfig(const TrackEventConfig&) = default;
19355 TrackEventConfig& TrackEventConfig::operator=(const TrackEventConfig&) = default;
19356 TrackEventConfig::TrackEventConfig(TrackEventConfig&&) noexcept = default;
19357 TrackEventConfig& TrackEventConfig::operator=(TrackEventConfig&&) = default;
19358 
operator ==(const TrackEventConfig & other) const19359 bool TrackEventConfig::operator==(const TrackEventConfig& other) const {
19360   return unknown_fields_ == other.unknown_fields_
19361    && disabled_categories_ == other.disabled_categories_
19362    && enabled_categories_ == other.enabled_categories_
19363    && disabled_tags_ == other.disabled_tags_
19364    && enabled_tags_ == other.enabled_tags_;
19365 }
19366 
ParseFromArray(const void * raw,size_t size)19367 bool TrackEventConfig::ParseFromArray(const void* raw, size_t size) {
19368   disabled_categories_.clear();
19369   enabled_categories_.clear();
19370   disabled_tags_.clear();
19371   enabled_tags_.clear();
19372   unknown_fields_.clear();
19373   bool packed_error = false;
19374 
19375   ::protozero::ProtoDecoder dec(raw, size);
19376   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
19377     if (field.id() < _has_field_.size()) {
19378       _has_field_.set(field.id());
19379     }
19380     switch (field.id()) {
19381       case 1 /* disabled_categories */:
19382         disabled_categories_.emplace_back();
19383         field.get(&disabled_categories_.back());
19384         break;
19385       case 2 /* enabled_categories */:
19386         enabled_categories_.emplace_back();
19387         field.get(&enabled_categories_.back());
19388         break;
19389       case 3 /* disabled_tags */:
19390         disabled_tags_.emplace_back();
19391         field.get(&disabled_tags_.back());
19392         break;
19393       case 4 /* enabled_tags */:
19394         enabled_tags_.emplace_back();
19395         field.get(&enabled_tags_.back());
19396         break;
19397       default:
19398         field.SerializeAndAppendTo(&unknown_fields_);
19399         break;
19400     }
19401   }
19402   return !packed_error && !dec.bytes_left();
19403 }
19404 
SerializeAsString() const19405 std::string TrackEventConfig::SerializeAsString() const {
19406   ::protozero::HeapBuffered<::protozero::Message> msg;
19407   Serialize(msg.get());
19408   return msg.SerializeAsString();
19409 }
19410 
SerializeAsArray() const19411 std::vector<uint8_t> TrackEventConfig::SerializeAsArray() const {
19412   ::protozero::HeapBuffered<::protozero::Message> msg;
19413   Serialize(msg.get());
19414   return msg.SerializeAsArray();
19415 }
19416 
Serialize(::protozero::Message * msg) const19417 void TrackEventConfig::Serialize(::protozero::Message* msg) const {
19418   // Field 1: disabled_categories
19419   for (auto& it : disabled_categories_) {
19420     msg->AppendString(1, it);
19421   }
19422 
19423   // Field 2: enabled_categories
19424   for (auto& it : enabled_categories_) {
19425     msg->AppendString(2, it);
19426   }
19427 
19428   // Field 3: disabled_tags
19429   for (auto& it : disabled_tags_) {
19430     msg->AppendString(3, it);
19431   }
19432 
19433   // Field 4: enabled_tags
19434   for (auto& it : enabled_tags_) {
19435     msg->AppendString(4, it);
19436   }
19437 
19438   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
19439 }
19440 
19441 }  // namespace perfetto
19442 }  // namespace protos
19443 }  // namespace gen
19444 #if defined(__GNUC__) || defined(__clang__)
19445 #pragma GCC diagnostic pop
19446 #endif
19447 // gen_amalgamated begin source: gen/protos/perfetto/config/chrome/chrome_config.gen.cc
19448 // gen_amalgamated begin header: gen/protos/perfetto/config/chrome/chrome_config.gen.h
19449 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
19450 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_CHROME_CHROME_CONFIG_PROTO_CPP_H_
19451 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_CHROME_CHROME_CONFIG_PROTO_CPP_H_
19452 
19453 #include <stdint.h>
19454 #include <bitset>
19455 #include <vector>
19456 #include <string>
19457 #include <type_traits>
19458 
19459 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
19460 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
19461 // gen_amalgamated expanded: #include "perfetto/base/export.h"
19462 
19463 namespace perfetto {
19464 namespace protos {
19465 namespace gen {
19466 class ChromeConfig;
19467 enum ChromeConfig_ClientPriority : int;
19468 }  // namespace perfetto
19469 }  // namespace protos
19470 }  // namespace gen
19471 
19472 namespace protozero {
19473 class Message;
19474 }  // namespace protozero
19475 
19476 namespace perfetto {
19477 namespace protos {
19478 namespace gen {
19479 enum ChromeConfig_ClientPriority : int {
19480   ChromeConfig_ClientPriority_UNKNOWN = 0,
19481   ChromeConfig_ClientPriority_BACKGROUND = 1,
19482   ChromeConfig_ClientPriority_USER_INITIATED = 2,
19483 };
19484 
19485 class PERFETTO_EXPORT ChromeConfig : public ::protozero::CppMessageObj {
19486  public:
19487   using ClientPriority = ChromeConfig_ClientPriority;
19488   static constexpr auto UNKNOWN = ChromeConfig_ClientPriority_UNKNOWN;
19489   static constexpr auto BACKGROUND = ChromeConfig_ClientPriority_BACKGROUND;
19490   static constexpr auto USER_INITIATED = ChromeConfig_ClientPriority_USER_INITIATED;
19491   static constexpr auto ClientPriority_MIN = ChromeConfig_ClientPriority_UNKNOWN;
19492   static constexpr auto ClientPriority_MAX = ChromeConfig_ClientPriority_USER_INITIATED;
19493   enum FieldNumbers {
19494     kTraceConfigFieldNumber = 1,
19495     kPrivacyFilteringEnabledFieldNumber = 2,
19496     kConvertToLegacyJsonFieldNumber = 3,
19497     kClientPriorityFieldNumber = 4,
19498     kJsonAgentLabelFilterFieldNumber = 5,
19499   };
19500 
19501   ChromeConfig();
19502   ~ChromeConfig() override;
19503   ChromeConfig(ChromeConfig&&) noexcept;
19504   ChromeConfig& operator=(ChromeConfig&&);
19505   ChromeConfig(const ChromeConfig&);
19506   ChromeConfig& operator=(const ChromeConfig&);
19507   bool operator==(const ChromeConfig&) const;
operator !=(const ChromeConfig & other) const19508   bool operator!=(const ChromeConfig& other) const { return !(*this == other); }
19509 
19510   bool ParseFromArray(const void*, size_t) override;
19511   std::string SerializeAsString() const override;
19512   std::vector<uint8_t> SerializeAsArray() const override;
19513   void Serialize(::protozero::Message*) const;
19514 
has_trace_config() const19515   bool has_trace_config() const { return _has_field_[1]; }
trace_config() const19516   const std::string& trace_config() const { return trace_config_; }
set_trace_config(const std::string & value)19517   void set_trace_config(const std::string& value) { trace_config_ = value; _has_field_.set(1); }
19518 
has_privacy_filtering_enabled() const19519   bool has_privacy_filtering_enabled() const { return _has_field_[2]; }
privacy_filtering_enabled() const19520   bool privacy_filtering_enabled() const { return privacy_filtering_enabled_; }
set_privacy_filtering_enabled(bool value)19521   void set_privacy_filtering_enabled(bool value) { privacy_filtering_enabled_ = value; _has_field_.set(2); }
19522 
has_convert_to_legacy_json() const19523   bool has_convert_to_legacy_json() const { return _has_field_[3]; }
convert_to_legacy_json() const19524   bool convert_to_legacy_json() const { return convert_to_legacy_json_; }
set_convert_to_legacy_json(bool value)19525   void set_convert_to_legacy_json(bool value) { convert_to_legacy_json_ = value; _has_field_.set(3); }
19526 
has_client_priority() const19527   bool has_client_priority() const { return _has_field_[4]; }
client_priority() const19528   ChromeConfig_ClientPriority client_priority() const { return client_priority_; }
set_client_priority(ChromeConfig_ClientPriority value)19529   void set_client_priority(ChromeConfig_ClientPriority value) { client_priority_ = value; _has_field_.set(4); }
19530 
has_json_agent_label_filter() const19531   bool has_json_agent_label_filter() const { return _has_field_[5]; }
json_agent_label_filter() const19532   const std::string& json_agent_label_filter() const { return json_agent_label_filter_; }
set_json_agent_label_filter(const std::string & value)19533   void set_json_agent_label_filter(const std::string& value) { json_agent_label_filter_ = value; _has_field_.set(5); }
19534 
19535  private:
19536   std::string trace_config_{};
19537   bool privacy_filtering_enabled_{};
19538   bool convert_to_legacy_json_{};
19539   ChromeConfig_ClientPriority client_priority_{};
19540   std::string json_agent_label_filter_{};
19541 
19542   // Allows to preserve unknown protobuf fields for compatibility
19543   // with future versions of .proto files.
19544   std::string unknown_fields_;
19545 
19546   std::bitset<6> _has_field_{};
19547 };
19548 
19549 }  // namespace perfetto
19550 }  // namespace protos
19551 }  // namespace gen
19552 
19553 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_CHROME_CHROME_CONFIG_PROTO_CPP_H_
19554 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
19555 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
19556 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
19557 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
19558 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
19559 #if defined(__GNUC__) || defined(__clang__)
19560 #pragma GCC diagnostic push
19561 #pragma GCC diagnostic ignored "-Wfloat-equal"
19562 #endif
19563 // gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
19564 
19565 namespace perfetto {
19566 namespace protos {
19567 namespace gen {
19568 
19569 ChromeConfig::ChromeConfig() = default;
19570 ChromeConfig::~ChromeConfig() = default;
19571 ChromeConfig::ChromeConfig(const ChromeConfig&) = default;
19572 ChromeConfig& ChromeConfig::operator=(const ChromeConfig&) = default;
19573 ChromeConfig::ChromeConfig(ChromeConfig&&) noexcept = default;
19574 ChromeConfig& ChromeConfig::operator=(ChromeConfig&&) = default;
19575 
operator ==(const ChromeConfig & other) const19576 bool ChromeConfig::operator==(const ChromeConfig& other) const {
19577   return unknown_fields_ == other.unknown_fields_
19578    && trace_config_ == other.trace_config_
19579    && privacy_filtering_enabled_ == other.privacy_filtering_enabled_
19580    && convert_to_legacy_json_ == other.convert_to_legacy_json_
19581    && client_priority_ == other.client_priority_
19582    && json_agent_label_filter_ == other.json_agent_label_filter_;
19583 }
19584 
ParseFromArray(const void * raw,size_t size)19585 bool ChromeConfig::ParseFromArray(const void* raw, size_t size) {
19586   unknown_fields_.clear();
19587   bool packed_error = false;
19588 
19589   ::protozero::ProtoDecoder dec(raw, size);
19590   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
19591     if (field.id() < _has_field_.size()) {
19592       _has_field_.set(field.id());
19593     }
19594     switch (field.id()) {
19595       case 1 /* trace_config */:
19596         field.get(&trace_config_);
19597         break;
19598       case 2 /* privacy_filtering_enabled */:
19599         field.get(&privacy_filtering_enabled_);
19600         break;
19601       case 3 /* convert_to_legacy_json */:
19602         field.get(&convert_to_legacy_json_);
19603         break;
19604       case 4 /* client_priority */:
19605         field.get(&client_priority_);
19606         break;
19607       case 5 /* json_agent_label_filter */:
19608         field.get(&json_agent_label_filter_);
19609         break;
19610       default:
19611         field.SerializeAndAppendTo(&unknown_fields_);
19612         break;
19613     }
19614   }
19615   return !packed_error && !dec.bytes_left();
19616 }
19617 
SerializeAsString() const19618 std::string ChromeConfig::SerializeAsString() const {
19619   ::protozero::HeapBuffered<::protozero::Message> msg;
19620   Serialize(msg.get());
19621   return msg.SerializeAsString();
19622 }
19623 
SerializeAsArray() const19624 std::vector<uint8_t> ChromeConfig::SerializeAsArray() const {
19625   ::protozero::HeapBuffered<::protozero::Message> msg;
19626   Serialize(msg.get());
19627   return msg.SerializeAsArray();
19628 }
19629 
Serialize(::protozero::Message * msg) const19630 void ChromeConfig::Serialize(::protozero::Message* msg) const {
19631   // Field 1: trace_config
19632   if (_has_field_[1]) {
19633     msg->AppendString(1, trace_config_);
19634   }
19635 
19636   // Field 2: privacy_filtering_enabled
19637   if (_has_field_[2]) {
19638     msg->AppendTinyVarInt(2, privacy_filtering_enabled_);
19639   }
19640 
19641   // Field 3: convert_to_legacy_json
19642   if (_has_field_[3]) {
19643     msg->AppendTinyVarInt(3, convert_to_legacy_json_);
19644   }
19645 
19646   // Field 4: client_priority
19647   if (_has_field_[4]) {
19648     msg->AppendVarInt(4, client_priority_);
19649   }
19650 
19651   // Field 5: json_agent_label_filter
19652   if (_has_field_[5]) {
19653     msg->AppendString(5, json_agent_label_filter_);
19654   }
19655 
19656   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
19657 }
19658 
19659 }  // namespace perfetto
19660 }  // namespace protos
19661 }  // namespace gen
19662 #if defined(__GNUC__) || defined(__clang__)
19663 #pragma GCC diagnostic pop
19664 #endif
19665 // gen_amalgamated begin source: gen/protos/perfetto/config/data_source_config.gen.cc
19666 // gen_amalgamated begin header: gen/protos/perfetto/config/test_config.gen.h
19667 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
19668 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TEST_CONFIG_PROTO_CPP_H_
19669 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TEST_CONFIG_PROTO_CPP_H_
19670 
19671 #include <stdint.h>
19672 #include <bitset>
19673 #include <vector>
19674 #include <string>
19675 #include <type_traits>
19676 
19677 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
19678 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
19679 // gen_amalgamated expanded: #include "perfetto/base/export.h"
19680 
19681 namespace perfetto {
19682 namespace protos {
19683 namespace gen {
19684 class TestConfig;
19685 class TestConfig_DummyFields;
19686 }  // namespace perfetto
19687 }  // namespace protos
19688 }  // namespace gen
19689 
19690 namespace protozero {
19691 class Message;
19692 }  // namespace protozero
19693 
19694 namespace perfetto {
19695 namespace protos {
19696 namespace gen {
19697 
19698 class PERFETTO_EXPORT TestConfig : public ::protozero::CppMessageObj {
19699  public:
19700   using DummyFields = TestConfig_DummyFields;
19701   enum FieldNumbers {
19702     kMessageCountFieldNumber = 1,
19703     kMaxMessagesPerSecondFieldNumber = 2,
19704     kSeedFieldNumber = 3,
19705     kMessageSizeFieldNumber = 4,
19706     kSendBatchOnRegisterFieldNumber = 5,
19707     kDummyFieldsFieldNumber = 6,
19708   };
19709 
19710   TestConfig();
19711   ~TestConfig() override;
19712   TestConfig(TestConfig&&) noexcept;
19713   TestConfig& operator=(TestConfig&&);
19714   TestConfig(const TestConfig&);
19715   TestConfig& operator=(const TestConfig&);
19716   bool operator==(const TestConfig&) const;
operator !=(const TestConfig & other) const19717   bool operator!=(const TestConfig& other) const { return !(*this == other); }
19718 
19719   bool ParseFromArray(const void*, size_t) override;
19720   std::string SerializeAsString() const override;
19721   std::vector<uint8_t> SerializeAsArray() const override;
19722   void Serialize(::protozero::Message*) const;
19723 
has_message_count() const19724   bool has_message_count() const { return _has_field_[1]; }
message_count() const19725   uint32_t message_count() const { return message_count_; }
set_message_count(uint32_t value)19726   void set_message_count(uint32_t value) { message_count_ = value; _has_field_.set(1); }
19727 
has_max_messages_per_second() const19728   bool has_max_messages_per_second() const { return _has_field_[2]; }
max_messages_per_second() const19729   uint32_t max_messages_per_second() const { return max_messages_per_second_; }
set_max_messages_per_second(uint32_t value)19730   void set_max_messages_per_second(uint32_t value) { max_messages_per_second_ = value; _has_field_.set(2); }
19731 
has_seed() const19732   bool has_seed() const { return _has_field_[3]; }
seed() const19733   uint32_t seed() const { return seed_; }
set_seed(uint32_t value)19734   void set_seed(uint32_t value) { seed_ = value; _has_field_.set(3); }
19735 
has_message_size() const19736   bool has_message_size() const { return _has_field_[4]; }
message_size() const19737   uint32_t message_size() const { return message_size_; }
set_message_size(uint32_t value)19738   void set_message_size(uint32_t value) { message_size_ = value; _has_field_.set(4); }
19739 
has_send_batch_on_register() const19740   bool has_send_batch_on_register() const { return _has_field_[5]; }
send_batch_on_register() const19741   bool send_batch_on_register() const { return send_batch_on_register_; }
set_send_batch_on_register(bool value)19742   void set_send_batch_on_register(bool value) { send_batch_on_register_ = value; _has_field_.set(5); }
19743 
has_dummy_fields() const19744   bool has_dummy_fields() const { return _has_field_[6]; }
dummy_fields() const19745   const TestConfig_DummyFields& dummy_fields() const { return *dummy_fields_; }
mutable_dummy_fields()19746   TestConfig_DummyFields* mutable_dummy_fields() { _has_field_.set(6); return dummy_fields_.get(); }
19747 
19748  private:
19749   uint32_t message_count_{};
19750   uint32_t max_messages_per_second_{};
19751   uint32_t seed_{};
19752   uint32_t message_size_{};
19753   bool send_batch_on_register_{};
19754   ::protozero::CopyablePtr<TestConfig_DummyFields> dummy_fields_;
19755 
19756   // Allows to preserve unknown protobuf fields for compatibility
19757   // with future versions of .proto files.
19758   std::string unknown_fields_;
19759 
19760   std::bitset<7> _has_field_{};
19761 };
19762 
19763 
19764 class PERFETTO_EXPORT TestConfig_DummyFields : public ::protozero::CppMessageObj {
19765  public:
19766   enum FieldNumbers {
19767     kFieldUint32FieldNumber = 1,
19768     kFieldInt32FieldNumber = 2,
19769     kFieldUint64FieldNumber = 3,
19770     kFieldInt64FieldNumber = 4,
19771     kFieldFixed64FieldNumber = 5,
19772     kFieldSfixed64FieldNumber = 6,
19773     kFieldFixed32FieldNumber = 7,
19774     kFieldSfixed32FieldNumber = 8,
19775     kFieldDoubleFieldNumber = 9,
19776     kFieldFloatFieldNumber = 10,
19777     kFieldSint64FieldNumber = 11,
19778     kFieldSint32FieldNumber = 12,
19779     kFieldStringFieldNumber = 13,
19780     kFieldBytesFieldNumber = 14,
19781   };
19782 
19783   TestConfig_DummyFields();
19784   ~TestConfig_DummyFields() override;
19785   TestConfig_DummyFields(TestConfig_DummyFields&&) noexcept;
19786   TestConfig_DummyFields& operator=(TestConfig_DummyFields&&);
19787   TestConfig_DummyFields(const TestConfig_DummyFields&);
19788   TestConfig_DummyFields& operator=(const TestConfig_DummyFields&);
19789   bool operator==(const TestConfig_DummyFields&) const;
operator !=(const TestConfig_DummyFields & other) const19790   bool operator!=(const TestConfig_DummyFields& other) const { return !(*this == other); }
19791 
19792   bool ParseFromArray(const void*, size_t) override;
19793   std::string SerializeAsString() const override;
19794   std::vector<uint8_t> SerializeAsArray() const override;
19795   void Serialize(::protozero::Message*) const;
19796 
has_field_uint32() const19797   bool has_field_uint32() const { return _has_field_[1]; }
field_uint32() const19798   uint32_t field_uint32() const { return field_uint32_; }
set_field_uint32(uint32_t value)19799   void set_field_uint32(uint32_t value) { field_uint32_ = value; _has_field_.set(1); }
19800 
has_field_int32() const19801   bool has_field_int32() const { return _has_field_[2]; }
field_int32() const19802   int32_t field_int32() const { return field_int32_; }
set_field_int32(int32_t value)19803   void set_field_int32(int32_t value) { field_int32_ = value; _has_field_.set(2); }
19804 
has_field_uint64() const19805   bool has_field_uint64() const { return _has_field_[3]; }
field_uint64() const19806   uint64_t field_uint64() const { return field_uint64_; }
set_field_uint64(uint64_t value)19807   void set_field_uint64(uint64_t value) { field_uint64_ = value; _has_field_.set(3); }
19808 
has_field_int64() const19809   bool has_field_int64() const { return _has_field_[4]; }
field_int64() const19810   int64_t field_int64() const { return field_int64_; }
set_field_int64(int64_t value)19811   void set_field_int64(int64_t value) { field_int64_ = value; _has_field_.set(4); }
19812 
has_field_fixed64() const19813   bool has_field_fixed64() const { return _has_field_[5]; }
field_fixed64() const19814   uint64_t field_fixed64() const { return field_fixed64_; }
set_field_fixed64(uint64_t value)19815   void set_field_fixed64(uint64_t value) { field_fixed64_ = value; _has_field_.set(5); }
19816 
has_field_sfixed64() const19817   bool has_field_sfixed64() const { return _has_field_[6]; }
field_sfixed64() const19818   int64_t field_sfixed64() const { return field_sfixed64_; }
set_field_sfixed64(int64_t value)19819   void set_field_sfixed64(int64_t value) { field_sfixed64_ = value; _has_field_.set(6); }
19820 
has_field_fixed32() const19821   bool has_field_fixed32() const { return _has_field_[7]; }
field_fixed32() const19822   uint32_t field_fixed32() const { return field_fixed32_; }
set_field_fixed32(uint32_t value)19823   void set_field_fixed32(uint32_t value) { field_fixed32_ = value; _has_field_.set(7); }
19824 
has_field_sfixed32() const19825   bool has_field_sfixed32() const { return _has_field_[8]; }
field_sfixed32() const19826   int32_t field_sfixed32() const { return field_sfixed32_; }
set_field_sfixed32(int32_t value)19827   void set_field_sfixed32(int32_t value) { field_sfixed32_ = value; _has_field_.set(8); }
19828 
has_field_double() const19829   bool has_field_double() const { return _has_field_[9]; }
field_double() const19830   double field_double() const { return field_double_; }
set_field_double(double value)19831   void set_field_double(double value) { field_double_ = value; _has_field_.set(9); }
19832 
has_field_float() const19833   bool has_field_float() const { return _has_field_[10]; }
field_float() const19834   float field_float() const { return field_float_; }
set_field_float(float value)19835   void set_field_float(float value) { field_float_ = value; _has_field_.set(10); }
19836 
has_field_sint64() const19837   bool has_field_sint64() const { return _has_field_[11]; }
field_sint64() const19838   int64_t field_sint64() const { return field_sint64_; }
set_field_sint64(int64_t value)19839   void set_field_sint64(int64_t value) { field_sint64_ = value; _has_field_.set(11); }
19840 
has_field_sint32() const19841   bool has_field_sint32() const { return _has_field_[12]; }
field_sint32() const19842   int32_t field_sint32() const { return field_sint32_; }
set_field_sint32(int32_t value)19843   void set_field_sint32(int32_t value) { field_sint32_ = value; _has_field_.set(12); }
19844 
has_field_string() const19845   bool has_field_string() const { return _has_field_[13]; }
field_string() const19846   const std::string& field_string() const { return field_string_; }
set_field_string(const std::string & value)19847   void set_field_string(const std::string& value) { field_string_ = value; _has_field_.set(13); }
19848 
has_field_bytes() const19849   bool has_field_bytes() const { return _has_field_[14]; }
field_bytes() const19850   const std::string& field_bytes() const { return field_bytes_; }
set_field_bytes(const std::string & value)19851   void set_field_bytes(const std::string& value) { field_bytes_ = value; _has_field_.set(14); }
set_field_bytes(const void * p,size_t s)19852   void set_field_bytes(const void* p, size_t s) { field_bytes_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(14); }
19853 
19854  private:
19855   uint32_t field_uint32_{};
19856   int32_t field_int32_{};
19857   uint64_t field_uint64_{};
19858   int64_t field_int64_{};
19859   uint64_t field_fixed64_{};
19860   int64_t field_sfixed64_{};
19861   uint32_t field_fixed32_{};
19862   int32_t field_sfixed32_{};
19863   double field_double_{};
19864   float field_float_{};
19865   int64_t field_sint64_{};
19866   int32_t field_sint32_{};
19867   std::string field_string_{};
19868   std::string field_bytes_{};
19869 
19870   // Allows to preserve unknown protobuf fields for compatibility
19871   // with future versions of .proto files.
19872   std::string unknown_fields_;
19873 
19874   std::bitset<15> _has_field_{};
19875 };
19876 
19877 }  // namespace perfetto
19878 }  // namespace protos
19879 }  // namespace gen
19880 
19881 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TEST_CONFIG_PROTO_CPP_H_
19882 // gen_amalgamated begin header: gen/protos/perfetto/config/interceptor_config.gen.h
19883 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
19884 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTOR_CONFIG_PROTO_CPP_H_
19885 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTOR_CONFIG_PROTO_CPP_H_
19886 
19887 #include <stdint.h>
19888 #include <bitset>
19889 #include <vector>
19890 #include <string>
19891 #include <type_traits>
19892 
19893 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
19894 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
19895 // gen_amalgamated expanded: #include "perfetto/base/export.h"
19896 
19897 namespace perfetto {
19898 namespace protos {
19899 namespace gen {
19900 class InterceptorConfig;
19901 }  // namespace perfetto
19902 }  // namespace protos
19903 }  // namespace gen
19904 
19905 namespace protozero {
19906 class Message;
19907 }  // namespace protozero
19908 
19909 namespace perfetto {
19910 namespace protos {
19911 namespace gen {
19912 
19913 class PERFETTO_EXPORT InterceptorConfig : public ::protozero::CppMessageObj {
19914  public:
19915   enum FieldNumbers {
19916     kNameFieldNumber = 1,
19917     kConsoleConfigFieldNumber = 100,
19918   };
19919 
19920   InterceptorConfig();
19921   ~InterceptorConfig() override;
19922   InterceptorConfig(InterceptorConfig&&) noexcept;
19923   InterceptorConfig& operator=(InterceptorConfig&&);
19924   InterceptorConfig(const InterceptorConfig&);
19925   InterceptorConfig& operator=(const InterceptorConfig&);
19926   bool operator==(const InterceptorConfig&) const;
operator !=(const InterceptorConfig & other) const19927   bool operator!=(const InterceptorConfig& other) const { return !(*this == other); }
19928 
19929   bool ParseFromArray(const void*, size_t) override;
19930   std::string SerializeAsString() const override;
19931   std::vector<uint8_t> SerializeAsArray() const override;
19932   void Serialize(::protozero::Message*) const;
19933 
has_name() const19934   bool has_name() const { return _has_field_[1]; }
name() const19935   const std::string& name() const { return name_; }
set_name(const std::string & value)19936   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
19937 
console_config_raw() const19938   const std::string& console_config_raw() const { return console_config_; }
set_console_config_raw(const std::string & raw)19939   void set_console_config_raw(const std::string& raw) { console_config_ = raw; _has_field_.set(100); }
19940 
19941  private:
19942   std::string name_{};
19943   std::string console_config_;  // [lazy=true]
19944 
19945   // Allows to preserve unknown protobuf fields for compatibility
19946   // with future versions of .proto files.
19947   std::string unknown_fields_;
19948 
19949   std::bitset<101> _has_field_{};
19950 };
19951 
19952 }  // namespace perfetto
19953 }  // namespace protos
19954 }  // namespace gen
19955 
19956 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTOR_CONFIG_PROTO_CPP_H_
19957 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
19958 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
19959 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
19960 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
19961 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
19962 #if defined(__GNUC__) || defined(__clang__)
19963 #pragma GCC diagnostic push
19964 #pragma GCC diagnostic ignored "-Wfloat-equal"
19965 #endif
19966 // gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
19967 // gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
19968 // gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
19969 // gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
19970 // gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
19971 
19972 namespace perfetto {
19973 namespace protos {
19974 namespace gen {
19975 
19976 DataSourceConfig::DataSourceConfig() = default;
19977 DataSourceConfig::~DataSourceConfig() = default;
19978 DataSourceConfig::DataSourceConfig(const DataSourceConfig&) = default;
19979 DataSourceConfig& DataSourceConfig::operator=(const DataSourceConfig&) = default;
19980 DataSourceConfig::DataSourceConfig(DataSourceConfig&&) noexcept = default;
19981 DataSourceConfig& DataSourceConfig::operator=(DataSourceConfig&&) = default;
19982 
operator ==(const DataSourceConfig & other) const19983 bool DataSourceConfig::operator==(const DataSourceConfig& other) const {
19984   return unknown_fields_ == other.unknown_fields_
19985    && name_ == other.name_
19986    && target_buffer_ == other.target_buffer_
19987    && trace_duration_ms_ == other.trace_duration_ms_
19988    && stop_timeout_ms_ == other.stop_timeout_ms_
19989    && enable_extra_guardrails_ == other.enable_extra_guardrails_
19990    && session_initiator_ == other.session_initiator_
19991    && tracing_session_id_ == other.tracing_session_id_
19992    && ftrace_config_ == other.ftrace_config_
19993    && inode_file_config_ == other.inode_file_config_
19994    && process_stats_config_ == other.process_stats_config_
19995    && sys_stats_config_ == other.sys_stats_config_
19996    && heapprofd_config_ == other.heapprofd_config_
19997    && java_hprof_config_ == other.java_hprof_config_
19998    && android_power_config_ == other.android_power_config_
19999    && android_log_config_ == other.android_log_config_
20000    && gpu_counter_config_ == other.gpu_counter_config_
20001    && packages_list_config_ == other.packages_list_config_
20002    && perf_event_config_ == other.perf_event_config_
20003    && vulkan_memory_config_ == other.vulkan_memory_config_
20004    && track_event_config_ == other.track_event_config_
20005    && android_polled_state_config_ == other.android_polled_state_config_
20006    && chrome_config_ == other.chrome_config_
20007    && interceptor_config_ == other.interceptor_config_
20008    && legacy_config_ == other.legacy_config_
20009    && for_testing_ == other.for_testing_;
20010 }
20011 
ParseFromArray(const void * raw,size_t size)20012 bool DataSourceConfig::ParseFromArray(const void* raw, size_t size) {
20013   unknown_fields_.clear();
20014   bool packed_error = false;
20015 
20016   ::protozero::ProtoDecoder dec(raw, size);
20017   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
20018     if (field.id() < _has_field_.size()) {
20019       _has_field_.set(field.id());
20020     }
20021     switch (field.id()) {
20022       case 1 /* name */:
20023         field.get(&name_);
20024         break;
20025       case 2 /* target_buffer */:
20026         field.get(&target_buffer_);
20027         break;
20028       case 3 /* trace_duration_ms */:
20029         field.get(&trace_duration_ms_);
20030         break;
20031       case 7 /* stop_timeout_ms */:
20032         field.get(&stop_timeout_ms_);
20033         break;
20034       case 6 /* enable_extra_guardrails */:
20035         field.get(&enable_extra_guardrails_);
20036         break;
20037       case 8 /* session_initiator */:
20038         field.get(&session_initiator_);
20039         break;
20040       case 4 /* tracing_session_id */:
20041         field.get(&tracing_session_id_);
20042         break;
20043       case 100 /* ftrace_config */:
20044         ftrace_config_ = field.as_std_string();
20045         break;
20046       case 102 /* inode_file_config */:
20047         inode_file_config_ = field.as_std_string();
20048         break;
20049       case 103 /* process_stats_config */:
20050         process_stats_config_ = field.as_std_string();
20051         break;
20052       case 104 /* sys_stats_config */:
20053         sys_stats_config_ = field.as_std_string();
20054         break;
20055       case 105 /* heapprofd_config */:
20056         heapprofd_config_ = field.as_std_string();
20057         break;
20058       case 110 /* java_hprof_config */:
20059         java_hprof_config_ = field.as_std_string();
20060         break;
20061       case 106 /* android_power_config */:
20062         android_power_config_ = field.as_std_string();
20063         break;
20064       case 107 /* android_log_config */:
20065         android_log_config_ = field.as_std_string();
20066         break;
20067       case 108 /* gpu_counter_config */:
20068         gpu_counter_config_ = field.as_std_string();
20069         break;
20070       case 109 /* packages_list_config */:
20071         packages_list_config_ = field.as_std_string();
20072         break;
20073       case 111 /* perf_event_config */:
20074         perf_event_config_ = field.as_std_string();
20075         break;
20076       case 112 /* vulkan_memory_config */:
20077         vulkan_memory_config_ = field.as_std_string();
20078         break;
20079       case 113 /* track_event_config */:
20080         track_event_config_ = field.as_std_string();
20081         break;
20082       case 114 /* android_polled_state_config */:
20083         android_polled_state_config_ = field.as_std_string();
20084         break;
20085       case 101 /* chrome_config */:
20086         (*chrome_config_).ParseFromArray(field.data(), field.size());
20087         break;
20088       case 115 /* interceptor_config */:
20089         (*interceptor_config_).ParseFromArray(field.data(), field.size());
20090         break;
20091       case 1000 /* legacy_config */:
20092         field.get(&legacy_config_);
20093         break;
20094       case 1001 /* for_testing */:
20095         (*for_testing_).ParseFromArray(field.data(), field.size());
20096         break;
20097       default:
20098         field.SerializeAndAppendTo(&unknown_fields_);
20099         break;
20100     }
20101   }
20102   return !packed_error && !dec.bytes_left();
20103 }
20104 
SerializeAsString() const20105 std::string DataSourceConfig::SerializeAsString() const {
20106   ::protozero::HeapBuffered<::protozero::Message> msg;
20107   Serialize(msg.get());
20108   return msg.SerializeAsString();
20109 }
20110 
SerializeAsArray() const20111 std::vector<uint8_t> DataSourceConfig::SerializeAsArray() const {
20112   ::protozero::HeapBuffered<::protozero::Message> msg;
20113   Serialize(msg.get());
20114   return msg.SerializeAsArray();
20115 }
20116 
Serialize(::protozero::Message * msg) const20117 void DataSourceConfig::Serialize(::protozero::Message* msg) const {
20118   // Field 1: name
20119   if (_has_field_[1]) {
20120     msg->AppendString(1, name_);
20121   }
20122 
20123   // Field 2: target_buffer
20124   if (_has_field_[2]) {
20125     msg->AppendVarInt(2, target_buffer_);
20126   }
20127 
20128   // Field 3: trace_duration_ms
20129   if (_has_field_[3]) {
20130     msg->AppendVarInt(3, trace_duration_ms_);
20131   }
20132 
20133   // Field 7: stop_timeout_ms
20134   if (_has_field_[7]) {
20135     msg->AppendVarInt(7, stop_timeout_ms_);
20136   }
20137 
20138   // Field 6: enable_extra_guardrails
20139   if (_has_field_[6]) {
20140     msg->AppendTinyVarInt(6, enable_extra_guardrails_);
20141   }
20142 
20143   // Field 8: session_initiator
20144   if (_has_field_[8]) {
20145     msg->AppendVarInt(8, session_initiator_);
20146   }
20147 
20148   // Field 4: tracing_session_id
20149   if (_has_field_[4]) {
20150     msg->AppendVarInt(4, tracing_session_id_);
20151   }
20152 
20153   // Field 100: ftrace_config
20154   if (_has_field_[100]) {
20155     msg->AppendString(100, ftrace_config_);
20156   }
20157 
20158   // Field 102: inode_file_config
20159   if (_has_field_[102]) {
20160     msg->AppendString(102, inode_file_config_);
20161   }
20162 
20163   // Field 103: process_stats_config
20164   if (_has_field_[103]) {
20165     msg->AppendString(103, process_stats_config_);
20166   }
20167 
20168   // Field 104: sys_stats_config
20169   if (_has_field_[104]) {
20170     msg->AppendString(104, sys_stats_config_);
20171   }
20172 
20173   // Field 105: heapprofd_config
20174   if (_has_field_[105]) {
20175     msg->AppendString(105, heapprofd_config_);
20176   }
20177 
20178   // Field 110: java_hprof_config
20179   if (_has_field_[110]) {
20180     msg->AppendString(110, java_hprof_config_);
20181   }
20182 
20183   // Field 106: android_power_config
20184   if (_has_field_[106]) {
20185     msg->AppendString(106, android_power_config_);
20186   }
20187 
20188   // Field 107: android_log_config
20189   if (_has_field_[107]) {
20190     msg->AppendString(107, android_log_config_);
20191   }
20192 
20193   // Field 108: gpu_counter_config
20194   if (_has_field_[108]) {
20195     msg->AppendString(108, gpu_counter_config_);
20196   }
20197 
20198   // Field 109: packages_list_config
20199   if (_has_field_[109]) {
20200     msg->AppendString(109, packages_list_config_);
20201   }
20202 
20203   // Field 111: perf_event_config
20204   if (_has_field_[111]) {
20205     msg->AppendString(111, perf_event_config_);
20206   }
20207 
20208   // Field 112: vulkan_memory_config
20209   if (_has_field_[112]) {
20210     msg->AppendString(112, vulkan_memory_config_);
20211   }
20212 
20213   // Field 113: track_event_config
20214   if (_has_field_[113]) {
20215     msg->AppendString(113, track_event_config_);
20216   }
20217 
20218   // Field 114: android_polled_state_config
20219   if (_has_field_[114]) {
20220     msg->AppendString(114, android_polled_state_config_);
20221   }
20222 
20223   // Field 101: chrome_config
20224   if (_has_field_[101]) {
20225     (*chrome_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(101));
20226   }
20227 
20228   // Field 115: interceptor_config
20229   if (_has_field_[115]) {
20230     (*interceptor_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(115));
20231   }
20232 
20233   // Field 1000: legacy_config
20234   if (_has_field_[1000]) {
20235     msg->AppendString(1000, legacy_config_);
20236   }
20237 
20238   // Field 1001: for_testing
20239   if (_has_field_[1001]) {
20240     (*for_testing_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1001));
20241   }
20242 
20243   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
20244 }
20245 
20246 }  // namespace perfetto
20247 }  // namespace protos
20248 }  // namespace gen
20249 #if defined(__GNUC__) || defined(__clang__)
20250 #pragma GCC diagnostic pop
20251 #endif
20252 // gen_amalgamated begin source: gen/protos/perfetto/config/interceptor_config.gen.cc
20253 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
20254 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
20255 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
20256 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
20257 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
20258 #if defined(__GNUC__) || defined(__clang__)
20259 #pragma GCC diagnostic push
20260 #pragma GCC diagnostic ignored "-Wfloat-equal"
20261 #endif
20262 // gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
20263 
20264 namespace perfetto {
20265 namespace protos {
20266 namespace gen {
20267 
20268 InterceptorConfig::InterceptorConfig() = default;
20269 InterceptorConfig::~InterceptorConfig() = default;
20270 InterceptorConfig::InterceptorConfig(const InterceptorConfig&) = default;
20271 InterceptorConfig& InterceptorConfig::operator=(const InterceptorConfig&) = default;
20272 InterceptorConfig::InterceptorConfig(InterceptorConfig&&) noexcept = default;
20273 InterceptorConfig& InterceptorConfig::operator=(InterceptorConfig&&) = default;
20274 
operator ==(const InterceptorConfig & other) const20275 bool InterceptorConfig::operator==(const InterceptorConfig& other) const {
20276   return unknown_fields_ == other.unknown_fields_
20277    && name_ == other.name_
20278    && console_config_ == other.console_config_;
20279 }
20280 
ParseFromArray(const void * raw,size_t size)20281 bool InterceptorConfig::ParseFromArray(const void* raw, size_t size) {
20282   unknown_fields_.clear();
20283   bool packed_error = false;
20284 
20285   ::protozero::ProtoDecoder dec(raw, size);
20286   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
20287     if (field.id() < _has_field_.size()) {
20288       _has_field_.set(field.id());
20289     }
20290     switch (field.id()) {
20291       case 1 /* name */:
20292         field.get(&name_);
20293         break;
20294       case 100 /* console_config */:
20295         console_config_ = field.as_std_string();
20296         break;
20297       default:
20298         field.SerializeAndAppendTo(&unknown_fields_);
20299         break;
20300     }
20301   }
20302   return !packed_error && !dec.bytes_left();
20303 }
20304 
SerializeAsString() const20305 std::string InterceptorConfig::SerializeAsString() const {
20306   ::protozero::HeapBuffered<::protozero::Message> msg;
20307   Serialize(msg.get());
20308   return msg.SerializeAsString();
20309 }
20310 
SerializeAsArray() const20311 std::vector<uint8_t> InterceptorConfig::SerializeAsArray() const {
20312   ::protozero::HeapBuffered<::protozero::Message> msg;
20313   Serialize(msg.get());
20314   return msg.SerializeAsArray();
20315 }
20316 
Serialize(::protozero::Message * msg) const20317 void InterceptorConfig::Serialize(::protozero::Message* msg) const {
20318   // Field 1: name
20319   if (_has_field_[1]) {
20320     msg->AppendString(1, name_);
20321   }
20322 
20323   // Field 100: console_config
20324   if (_has_field_[100]) {
20325     msg->AppendString(100, console_config_);
20326   }
20327 
20328   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
20329 }
20330 
20331 }  // namespace perfetto
20332 }  // namespace protos
20333 }  // namespace gen
20334 #if defined(__GNUC__) || defined(__clang__)
20335 #pragma GCC diagnostic pop
20336 #endif
20337 // gen_amalgamated begin source: gen/protos/perfetto/config/stress_test_config.gen.cc
20338 // gen_amalgamated begin header: gen/protos/perfetto/config/stress_test_config.gen.h
20339 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
20340 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STRESS_TEST_CONFIG_PROTO_CPP_H_
20341 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STRESS_TEST_CONFIG_PROTO_CPP_H_
20342 
20343 #include <stdint.h>
20344 #include <bitset>
20345 #include <vector>
20346 #include <string>
20347 #include <type_traits>
20348 
20349 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
20350 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
20351 // gen_amalgamated expanded: #include "perfetto/base/export.h"
20352 
20353 namespace perfetto {
20354 namespace protos {
20355 namespace gen {
20356 class StressTestConfig;
20357 class StressTestConfig_WriterTiming;
20358 class TraceConfig;
20359 class TraceConfig_TraceFilter;
20360 class TraceConfig_IncidentReportConfig;
20361 class TraceConfig_IncrementalStateConfig;
20362 class TraceConfig_TriggerConfig;
20363 class TraceConfig_TriggerConfig_Trigger;
20364 class TraceConfig_GuardrailOverrides;
20365 class TraceConfig_StatsdMetadata;
20366 class TraceConfig_ProducerConfig;
20367 class TraceConfig_BuiltinDataSource;
20368 class TraceConfig_DataSource;
20369 class DataSourceConfig;
20370 class TestConfig;
20371 class TestConfig_DummyFields;
20372 class InterceptorConfig;
20373 class ChromeConfig;
20374 class TraceConfig_BufferConfig;
20375 enum TraceConfig_LockdownModeOperation : int;
20376 enum TraceConfig_CompressionType : int;
20377 enum TraceConfig_StatsdLogging : int;
20378 enum TraceConfig_TriggerConfig_TriggerMode : int;
20379 enum BuiltinClock : int;
20380 enum DataSourceConfig_SessionInitiator : int;
20381 enum ChromeConfig_ClientPriority : int;
20382 enum TraceConfig_BufferConfig_FillPolicy : int;
20383 }  // namespace perfetto
20384 }  // namespace protos
20385 }  // namespace gen
20386 
20387 namespace protozero {
20388 class Message;
20389 }  // namespace protozero
20390 
20391 namespace perfetto {
20392 namespace protos {
20393 namespace gen {
20394 
20395 class PERFETTO_EXPORT StressTestConfig : public ::protozero::CppMessageObj {
20396  public:
20397   using WriterTiming = StressTestConfig_WriterTiming;
20398   enum FieldNumbers {
20399     kTraceConfigFieldNumber = 1,
20400     kShmemSizeKbFieldNumber = 2,
20401     kShmemPageSizeKbFieldNumber = 3,
20402     kNumProcessesFieldNumber = 4,
20403     kNumThreadsFieldNumber = 5,
20404     kMaxEventsFieldNumber = 6,
20405     kNestingFieldNumber = 7,
20406     kSteadyStateTimingsFieldNumber = 8,
20407     kBurstPeriodMsFieldNumber = 9,
20408     kBurstDurationMsFieldNumber = 10,
20409     kBurstTimingsFieldNumber = 11,
20410   };
20411 
20412   StressTestConfig();
20413   ~StressTestConfig() override;
20414   StressTestConfig(StressTestConfig&&) noexcept;
20415   StressTestConfig& operator=(StressTestConfig&&);
20416   StressTestConfig(const StressTestConfig&);
20417   StressTestConfig& operator=(const StressTestConfig&);
20418   bool operator==(const StressTestConfig&) const;
operator !=(const StressTestConfig & other) const20419   bool operator!=(const StressTestConfig& other) const { return !(*this == other); }
20420 
20421   bool ParseFromArray(const void*, size_t) override;
20422   std::string SerializeAsString() const override;
20423   std::vector<uint8_t> SerializeAsArray() const override;
20424   void Serialize(::protozero::Message*) const;
20425 
has_trace_config() const20426   bool has_trace_config() const { return _has_field_[1]; }
trace_config() const20427   const TraceConfig& trace_config() const { return *trace_config_; }
mutable_trace_config()20428   TraceConfig* mutable_trace_config() { _has_field_.set(1); return trace_config_.get(); }
20429 
has_shmem_size_kb() const20430   bool has_shmem_size_kb() const { return _has_field_[2]; }
shmem_size_kb() const20431   uint32_t shmem_size_kb() const { return shmem_size_kb_; }
set_shmem_size_kb(uint32_t value)20432   void set_shmem_size_kb(uint32_t value) { shmem_size_kb_ = value; _has_field_.set(2); }
20433 
has_shmem_page_size_kb() const20434   bool has_shmem_page_size_kb() const { return _has_field_[3]; }
shmem_page_size_kb() const20435   uint32_t shmem_page_size_kb() const { return shmem_page_size_kb_; }
set_shmem_page_size_kb(uint32_t value)20436   void set_shmem_page_size_kb(uint32_t value) { shmem_page_size_kb_ = value; _has_field_.set(3); }
20437 
has_num_processes() const20438   bool has_num_processes() const { return _has_field_[4]; }
num_processes() const20439   uint32_t num_processes() const { return num_processes_; }
set_num_processes(uint32_t value)20440   void set_num_processes(uint32_t value) { num_processes_ = value; _has_field_.set(4); }
20441 
has_num_threads() const20442   bool has_num_threads() const { return _has_field_[5]; }
num_threads() const20443   uint32_t num_threads() const { return num_threads_; }
set_num_threads(uint32_t value)20444   void set_num_threads(uint32_t value) { num_threads_ = value; _has_field_.set(5); }
20445 
has_max_events() const20446   bool has_max_events() const { return _has_field_[6]; }
max_events() const20447   uint32_t max_events() const { return max_events_; }
set_max_events(uint32_t value)20448   void set_max_events(uint32_t value) { max_events_ = value; _has_field_.set(6); }
20449 
has_nesting() const20450   bool has_nesting() const { return _has_field_[7]; }
nesting() const20451   uint32_t nesting() const { return nesting_; }
set_nesting(uint32_t value)20452   void set_nesting(uint32_t value) { nesting_ = value; _has_field_.set(7); }
20453 
has_steady_state_timings() const20454   bool has_steady_state_timings() const { return _has_field_[8]; }
steady_state_timings() const20455   const StressTestConfig_WriterTiming& steady_state_timings() const { return *steady_state_timings_; }
mutable_steady_state_timings()20456   StressTestConfig_WriterTiming* mutable_steady_state_timings() { _has_field_.set(8); return steady_state_timings_.get(); }
20457 
has_burst_period_ms() const20458   bool has_burst_period_ms() const { return _has_field_[9]; }
burst_period_ms() const20459   uint32_t burst_period_ms() const { return burst_period_ms_; }
set_burst_period_ms(uint32_t value)20460   void set_burst_period_ms(uint32_t value) { burst_period_ms_ = value; _has_field_.set(9); }
20461 
has_burst_duration_ms() const20462   bool has_burst_duration_ms() const { return _has_field_[10]; }
burst_duration_ms() const20463   uint32_t burst_duration_ms() const { return burst_duration_ms_; }
set_burst_duration_ms(uint32_t value)20464   void set_burst_duration_ms(uint32_t value) { burst_duration_ms_ = value; _has_field_.set(10); }
20465 
has_burst_timings() const20466   bool has_burst_timings() const { return _has_field_[11]; }
burst_timings() const20467   const StressTestConfig_WriterTiming& burst_timings() const { return *burst_timings_; }
mutable_burst_timings()20468   StressTestConfig_WriterTiming* mutable_burst_timings() { _has_field_.set(11); return burst_timings_.get(); }
20469 
20470  private:
20471   ::protozero::CopyablePtr<TraceConfig> trace_config_;
20472   uint32_t shmem_size_kb_{};
20473   uint32_t shmem_page_size_kb_{};
20474   uint32_t num_processes_{};
20475   uint32_t num_threads_{};
20476   uint32_t max_events_{};
20477   uint32_t nesting_{};
20478   ::protozero::CopyablePtr<StressTestConfig_WriterTiming> steady_state_timings_;
20479   uint32_t burst_period_ms_{};
20480   uint32_t burst_duration_ms_{};
20481   ::protozero::CopyablePtr<StressTestConfig_WriterTiming> burst_timings_;
20482 
20483   // Allows to preserve unknown protobuf fields for compatibility
20484   // with future versions of .proto files.
20485   std::string unknown_fields_;
20486 
20487   std::bitset<12> _has_field_{};
20488 };
20489 
20490 
20491 class PERFETTO_EXPORT StressTestConfig_WriterTiming : public ::protozero::CppMessageObj {
20492  public:
20493   enum FieldNumbers {
20494     kPayloadMeanFieldNumber = 1,
20495     kPayloadStddevFieldNumber = 2,
20496     kRateMeanFieldNumber = 3,
20497     kRateStddevFieldNumber = 4,
20498     kPayloadWriteTimeMsFieldNumber = 5,
20499   };
20500 
20501   StressTestConfig_WriterTiming();
20502   ~StressTestConfig_WriterTiming() override;
20503   StressTestConfig_WriterTiming(StressTestConfig_WriterTiming&&) noexcept;
20504   StressTestConfig_WriterTiming& operator=(StressTestConfig_WriterTiming&&);
20505   StressTestConfig_WriterTiming(const StressTestConfig_WriterTiming&);
20506   StressTestConfig_WriterTiming& operator=(const StressTestConfig_WriterTiming&);
20507   bool operator==(const StressTestConfig_WriterTiming&) const;
operator !=(const StressTestConfig_WriterTiming & other) const20508   bool operator!=(const StressTestConfig_WriterTiming& other) const { return !(*this == other); }
20509 
20510   bool ParseFromArray(const void*, size_t) override;
20511   std::string SerializeAsString() const override;
20512   std::vector<uint8_t> SerializeAsArray() const override;
20513   void Serialize(::protozero::Message*) const;
20514 
has_payload_mean() const20515   bool has_payload_mean() const { return _has_field_[1]; }
payload_mean() const20516   double payload_mean() const { return payload_mean_; }
set_payload_mean(double value)20517   void set_payload_mean(double value) { payload_mean_ = value; _has_field_.set(1); }
20518 
has_payload_stddev() const20519   bool has_payload_stddev() const { return _has_field_[2]; }
payload_stddev() const20520   double payload_stddev() const { return payload_stddev_; }
set_payload_stddev(double value)20521   void set_payload_stddev(double value) { payload_stddev_ = value; _has_field_.set(2); }
20522 
has_rate_mean() const20523   bool has_rate_mean() const { return _has_field_[3]; }
rate_mean() const20524   double rate_mean() const { return rate_mean_; }
set_rate_mean(double value)20525   void set_rate_mean(double value) { rate_mean_ = value; _has_field_.set(3); }
20526 
has_rate_stddev() const20527   bool has_rate_stddev() const { return _has_field_[4]; }
rate_stddev() const20528   double rate_stddev() const { return rate_stddev_; }
set_rate_stddev(double value)20529   void set_rate_stddev(double value) { rate_stddev_ = value; _has_field_.set(4); }
20530 
has_payload_write_time_ms() const20531   bool has_payload_write_time_ms() const { return _has_field_[5]; }
payload_write_time_ms() const20532   uint32_t payload_write_time_ms() const { return payload_write_time_ms_; }
set_payload_write_time_ms(uint32_t value)20533   void set_payload_write_time_ms(uint32_t value) { payload_write_time_ms_ = value; _has_field_.set(5); }
20534 
20535  private:
20536   double payload_mean_{};
20537   double payload_stddev_{};
20538   double rate_mean_{};
20539   double rate_stddev_{};
20540   uint32_t payload_write_time_ms_{};
20541 
20542   // Allows to preserve unknown protobuf fields for compatibility
20543   // with future versions of .proto files.
20544   std::string unknown_fields_;
20545 
20546   std::bitset<6> _has_field_{};
20547 };
20548 
20549 }  // namespace perfetto
20550 }  // namespace protos
20551 }  // namespace gen
20552 
20553 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STRESS_TEST_CONFIG_PROTO_CPP_H_
20554 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
20555 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
20556 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
20557 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
20558 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
20559 #if defined(__GNUC__) || defined(__clang__)
20560 #pragma GCC diagnostic push
20561 #pragma GCC diagnostic ignored "-Wfloat-equal"
20562 #endif
20563 // gen_amalgamated expanded: #include "protos/perfetto/config/stress_test_config.gen.h"
20564 // gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.gen.h"
20565 // gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"
20566 // gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
20567 // gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"
20568 // gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
20569 // gen_amalgamated expanded: #include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
20570 // gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
20571 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/perf_event_config.gen.h"
20572 // gen_amalgamated expanded: #include "protos/perfetto/common/perf_events.gen.h"
20573 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/java_hprof_config.gen.h"
20574 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/heapprofd_config.gen.h"
20575 // gen_amalgamated expanded: #include "protos/perfetto/config/process_stats/process_stats_config.gen.h"
20576 // gen_amalgamated expanded: #include "protos/perfetto/config/power/android_power_config.gen.h"
20577 // gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
20578 // gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
20579 // gen_amalgamated expanded: #include "protos/perfetto/config/inode_file/inode_file_config.gen.h"
20580 // gen_amalgamated expanded: #include "protos/perfetto/config/gpu/vulkan_memory_config.gen.h"
20581 // gen_amalgamated expanded: #include "protos/perfetto/config/gpu/gpu_counter_config.gen.h"
20582 // gen_amalgamated expanded: #include "protos/perfetto/config/ftrace/ftrace_config.gen.h"
20583 // gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
20584 // gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_config.gen.h"
20585 // gen_amalgamated expanded: #include "protos/perfetto/config/android/android_polled_state_config.gen.h"
20586 // gen_amalgamated expanded: #include "protos/perfetto/config/android/android_log_config.gen.h"
20587 // gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
20588 
20589 namespace perfetto {
20590 namespace protos {
20591 namespace gen {
20592 
20593 StressTestConfig::StressTestConfig() = default;
20594 StressTestConfig::~StressTestConfig() = default;
20595 StressTestConfig::StressTestConfig(const StressTestConfig&) = default;
20596 StressTestConfig& StressTestConfig::operator=(const StressTestConfig&) = default;
20597 StressTestConfig::StressTestConfig(StressTestConfig&&) noexcept = default;
20598 StressTestConfig& StressTestConfig::operator=(StressTestConfig&&) = default;
20599 
operator ==(const StressTestConfig & other) const20600 bool StressTestConfig::operator==(const StressTestConfig& other) const {
20601   return unknown_fields_ == other.unknown_fields_
20602    && trace_config_ == other.trace_config_
20603    && shmem_size_kb_ == other.shmem_size_kb_
20604    && shmem_page_size_kb_ == other.shmem_page_size_kb_
20605    && num_processes_ == other.num_processes_
20606    && num_threads_ == other.num_threads_
20607    && max_events_ == other.max_events_
20608    && nesting_ == other.nesting_
20609    && steady_state_timings_ == other.steady_state_timings_
20610    && burst_period_ms_ == other.burst_period_ms_
20611    && burst_duration_ms_ == other.burst_duration_ms_
20612    && burst_timings_ == other.burst_timings_;
20613 }
20614 
ParseFromArray(const void * raw,size_t size)20615 bool StressTestConfig::ParseFromArray(const void* raw, size_t size) {
20616   unknown_fields_.clear();
20617   bool packed_error = false;
20618 
20619   ::protozero::ProtoDecoder dec(raw, size);
20620   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
20621     if (field.id() < _has_field_.size()) {
20622       _has_field_.set(field.id());
20623     }
20624     switch (field.id()) {
20625       case 1 /* trace_config */:
20626         (*trace_config_).ParseFromArray(field.data(), field.size());
20627         break;
20628       case 2 /* shmem_size_kb */:
20629         field.get(&shmem_size_kb_);
20630         break;
20631       case 3 /* shmem_page_size_kb */:
20632         field.get(&shmem_page_size_kb_);
20633         break;
20634       case 4 /* num_processes */:
20635         field.get(&num_processes_);
20636         break;
20637       case 5 /* num_threads */:
20638         field.get(&num_threads_);
20639         break;
20640       case 6 /* max_events */:
20641         field.get(&max_events_);
20642         break;
20643       case 7 /* nesting */:
20644         field.get(&nesting_);
20645         break;
20646       case 8 /* steady_state_timings */:
20647         (*steady_state_timings_).ParseFromArray(field.data(), field.size());
20648         break;
20649       case 9 /* burst_period_ms */:
20650         field.get(&burst_period_ms_);
20651         break;
20652       case 10 /* burst_duration_ms */:
20653         field.get(&burst_duration_ms_);
20654         break;
20655       case 11 /* burst_timings */:
20656         (*burst_timings_).ParseFromArray(field.data(), field.size());
20657         break;
20658       default:
20659         field.SerializeAndAppendTo(&unknown_fields_);
20660         break;
20661     }
20662   }
20663   return !packed_error && !dec.bytes_left();
20664 }
20665 
SerializeAsString() const20666 std::string StressTestConfig::SerializeAsString() const {
20667   ::protozero::HeapBuffered<::protozero::Message> msg;
20668   Serialize(msg.get());
20669   return msg.SerializeAsString();
20670 }
20671 
SerializeAsArray() const20672 std::vector<uint8_t> StressTestConfig::SerializeAsArray() const {
20673   ::protozero::HeapBuffered<::protozero::Message> msg;
20674   Serialize(msg.get());
20675   return msg.SerializeAsArray();
20676 }
20677 
Serialize(::protozero::Message * msg) const20678 void StressTestConfig::Serialize(::protozero::Message* msg) const {
20679   // Field 1: trace_config
20680   if (_has_field_[1]) {
20681     (*trace_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
20682   }
20683 
20684   // Field 2: shmem_size_kb
20685   if (_has_field_[2]) {
20686     msg->AppendVarInt(2, shmem_size_kb_);
20687   }
20688 
20689   // Field 3: shmem_page_size_kb
20690   if (_has_field_[3]) {
20691     msg->AppendVarInt(3, shmem_page_size_kb_);
20692   }
20693 
20694   // Field 4: num_processes
20695   if (_has_field_[4]) {
20696     msg->AppendVarInt(4, num_processes_);
20697   }
20698 
20699   // Field 5: num_threads
20700   if (_has_field_[5]) {
20701     msg->AppendVarInt(5, num_threads_);
20702   }
20703 
20704   // Field 6: max_events
20705   if (_has_field_[6]) {
20706     msg->AppendVarInt(6, max_events_);
20707   }
20708 
20709   // Field 7: nesting
20710   if (_has_field_[7]) {
20711     msg->AppendVarInt(7, nesting_);
20712   }
20713 
20714   // Field 8: steady_state_timings
20715   if (_has_field_[8]) {
20716     (*steady_state_timings_).Serialize(msg->BeginNestedMessage<::protozero::Message>(8));
20717   }
20718 
20719   // Field 9: burst_period_ms
20720   if (_has_field_[9]) {
20721     msg->AppendVarInt(9, burst_period_ms_);
20722   }
20723 
20724   // Field 10: burst_duration_ms
20725   if (_has_field_[10]) {
20726     msg->AppendVarInt(10, burst_duration_ms_);
20727   }
20728 
20729   // Field 11: burst_timings
20730   if (_has_field_[11]) {
20731     (*burst_timings_).Serialize(msg->BeginNestedMessage<::protozero::Message>(11));
20732   }
20733 
20734   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
20735 }
20736 
20737 
20738 StressTestConfig_WriterTiming::StressTestConfig_WriterTiming() = default;
20739 StressTestConfig_WriterTiming::~StressTestConfig_WriterTiming() = default;
20740 StressTestConfig_WriterTiming::StressTestConfig_WriterTiming(const StressTestConfig_WriterTiming&) = default;
20741 StressTestConfig_WriterTiming& StressTestConfig_WriterTiming::operator=(const StressTestConfig_WriterTiming&) = default;
20742 StressTestConfig_WriterTiming::StressTestConfig_WriterTiming(StressTestConfig_WriterTiming&&) noexcept = default;
20743 StressTestConfig_WriterTiming& StressTestConfig_WriterTiming::operator=(StressTestConfig_WriterTiming&&) = default;
20744 
operator ==(const StressTestConfig_WriterTiming & other) const20745 bool StressTestConfig_WriterTiming::operator==(const StressTestConfig_WriterTiming& other) const {
20746   return unknown_fields_ == other.unknown_fields_
20747    && payload_mean_ == other.payload_mean_
20748    && payload_stddev_ == other.payload_stddev_
20749    && rate_mean_ == other.rate_mean_
20750    && rate_stddev_ == other.rate_stddev_
20751    && payload_write_time_ms_ == other.payload_write_time_ms_;
20752 }
20753 
ParseFromArray(const void * raw,size_t size)20754 bool StressTestConfig_WriterTiming::ParseFromArray(const void* raw, size_t size) {
20755   unknown_fields_.clear();
20756   bool packed_error = false;
20757 
20758   ::protozero::ProtoDecoder dec(raw, size);
20759   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
20760     if (field.id() < _has_field_.size()) {
20761       _has_field_.set(field.id());
20762     }
20763     switch (field.id()) {
20764       case 1 /* payload_mean */:
20765         field.get(&payload_mean_);
20766         break;
20767       case 2 /* payload_stddev */:
20768         field.get(&payload_stddev_);
20769         break;
20770       case 3 /* rate_mean */:
20771         field.get(&rate_mean_);
20772         break;
20773       case 4 /* rate_stddev */:
20774         field.get(&rate_stddev_);
20775         break;
20776       case 5 /* payload_write_time_ms */:
20777         field.get(&payload_write_time_ms_);
20778         break;
20779       default:
20780         field.SerializeAndAppendTo(&unknown_fields_);
20781         break;
20782     }
20783   }
20784   return !packed_error && !dec.bytes_left();
20785 }
20786 
SerializeAsString() const20787 std::string StressTestConfig_WriterTiming::SerializeAsString() const {
20788   ::protozero::HeapBuffered<::protozero::Message> msg;
20789   Serialize(msg.get());
20790   return msg.SerializeAsString();
20791 }
20792 
SerializeAsArray() const20793 std::vector<uint8_t> StressTestConfig_WriterTiming::SerializeAsArray() const {
20794   ::protozero::HeapBuffered<::protozero::Message> msg;
20795   Serialize(msg.get());
20796   return msg.SerializeAsArray();
20797 }
20798 
Serialize(::protozero::Message * msg) const20799 void StressTestConfig_WriterTiming::Serialize(::protozero::Message* msg) const {
20800   // Field 1: payload_mean
20801   if (_has_field_[1]) {
20802     msg->AppendFixed(1, payload_mean_);
20803   }
20804 
20805   // Field 2: payload_stddev
20806   if (_has_field_[2]) {
20807     msg->AppendFixed(2, payload_stddev_);
20808   }
20809 
20810   // Field 3: rate_mean
20811   if (_has_field_[3]) {
20812     msg->AppendFixed(3, rate_mean_);
20813   }
20814 
20815   // Field 4: rate_stddev
20816   if (_has_field_[4]) {
20817     msg->AppendFixed(4, rate_stddev_);
20818   }
20819 
20820   // Field 5: payload_write_time_ms
20821   if (_has_field_[5]) {
20822     msg->AppendVarInt(5, payload_write_time_ms_);
20823   }
20824 
20825   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
20826 }
20827 
20828 }  // namespace perfetto
20829 }  // namespace protos
20830 }  // namespace gen
20831 #if defined(__GNUC__) || defined(__clang__)
20832 #pragma GCC diagnostic pop
20833 #endif
20834 // gen_amalgamated begin source: gen/protos/perfetto/config/test_config.gen.cc
20835 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
20836 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
20837 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
20838 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
20839 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
20840 #if defined(__GNUC__) || defined(__clang__)
20841 #pragma GCC diagnostic push
20842 #pragma GCC diagnostic ignored "-Wfloat-equal"
20843 #endif
20844 // gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
20845 
20846 namespace perfetto {
20847 namespace protos {
20848 namespace gen {
20849 
20850 TestConfig::TestConfig() = default;
20851 TestConfig::~TestConfig() = default;
20852 TestConfig::TestConfig(const TestConfig&) = default;
20853 TestConfig& TestConfig::operator=(const TestConfig&) = default;
20854 TestConfig::TestConfig(TestConfig&&) noexcept = default;
20855 TestConfig& TestConfig::operator=(TestConfig&&) = default;
20856 
operator ==(const TestConfig & other) const20857 bool TestConfig::operator==(const TestConfig& other) const {
20858   return unknown_fields_ == other.unknown_fields_
20859    && message_count_ == other.message_count_
20860    && max_messages_per_second_ == other.max_messages_per_second_
20861    && seed_ == other.seed_
20862    && message_size_ == other.message_size_
20863    && send_batch_on_register_ == other.send_batch_on_register_
20864    && dummy_fields_ == other.dummy_fields_;
20865 }
20866 
ParseFromArray(const void * raw,size_t size)20867 bool TestConfig::ParseFromArray(const void* raw, size_t size) {
20868   unknown_fields_.clear();
20869   bool packed_error = false;
20870 
20871   ::protozero::ProtoDecoder dec(raw, size);
20872   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
20873     if (field.id() < _has_field_.size()) {
20874       _has_field_.set(field.id());
20875     }
20876     switch (field.id()) {
20877       case 1 /* message_count */:
20878         field.get(&message_count_);
20879         break;
20880       case 2 /* max_messages_per_second */:
20881         field.get(&max_messages_per_second_);
20882         break;
20883       case 3 /* seed */:
20884         field.get(&seed_);
20885         break;
20886       case 4 /* message_size */:
20887         field.get(&message_size_);
20888         break;
20889       case 5 /* send_batch_on_register */:
20890         field.get(&send_batch_on_register_);
20891         break;
20892       case 6 /* dummy_fields */:
20893         (*dummy_fields_).ParseFromArray(field.data(), field.size());
20894         break;
20895       default:
20896         field.SerializeAndAppendTo(&unknown_fields_);
20897         break;
20898     }
20899   }
20900   return !packed_error && !dec.bytes_left();
20901 }
20902 
SerializeAsString() const20903 std::string TestConfig::SerializeAsString() const {
20904   ::protozero::HeapBuffered<::protozero::Message> msg;
20905   Serialize(msg.get());
20906   return msg.SerializeAsString();
20907 }
20908 
SerializeAsArray() const20909 std::vector<uint8_t> TestConfig::SerializeAsArray() const {
20910   ::protozero::HeapBuffered<::protozero::Message> msg;
20911   Serialize(msg.get());
20912   return msg.SerializeAsArray();
20913 }
20914 
Serialize(::protozero::Message * msg) const20915 void TestConfig::Serialize(::protozero::Message* msg) const {
20916   // Field 1: message_count
20917   if (_has_field_[1]) {
20918     msg->AppendVarInt(1, message_count_);
20919   }
20920 
20921   // Field 2: max_messages_per_second
20922   if (_has_field_[2]) {
20923     msg->AppendVarInt(2, max_messages_per_second_);
20924   }
20925 
20926   // Field 3: seed
20927   if (_has_field_[3]) {
20928     msg->AppendVarInt(3, seed_);
20929   }
20930 
20931   // Field 4: message_size
20932   if (_has_field_[4]) {
20933     msg->AppendVarInt(4, message_size_);
20934   }
20935 
20936   // Field 5: send_batch_on_register
20937   if (_has_field_[5]) {
20938     msg->AppendTinyVarInt(5, send_batch_on_register_);
20939   }
20940 
20941   // Field 6: dummy_fields
20942   if (_has_field_[6]) {
20943     (*dummy_fields_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
20944   }
20945 
20946   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
20947 }
20948 
20949 
20950 TestConfig_DummyFields::TestConfig_DummyFields() = default;
20951 TestConfig_DummyFields::~TestConfig_DummyFields() = default;
20952 TestConfig_DummyFields::TestConfig_DummyFields(const TestConfig_DummyFields&) = default;
20953 TestConfig_DummyFields& TestConfig_DummyFields::operator=(const TestConfig_DummyFields&) = default;
20954 TestConfig_DummyFields::TestConfig_DummyFields(TestConfig_DummyFields&&) noexcept = default;
20955 TestConfig_DummyFields& TestConfig_DummyFields::operator=(TestConfig_DummyFields&&) = default;
20956 
operator ==(const TestConfig_DummyFields & other) const20957 bool TestConfig_DummyFields::operator==(const TestConfig_DummyFields& other) const {
20958   return unknown_fields_ == other.unknown_fields_
20959    && field_uint32_ == other.field_uint32_
20960    && field_int32_ == other.field_int32_
20961    && field_uint64_ == other.field_uint64_
20962    && field_int64_ == other.field_int64_
20963    && field_fixed64_ == other.field_fixed64_
20964    && field_sfixed64_ == other.field_sfixed64_
20965    && field_fixed32_ == other.field_fixed32_
20966    && field_sfixed32_ == other.field_sfixed32_
20967    && field_double_ == other.field_double_
20968    && field_float_ == other.field_float_
20969    && field_sint64_ == other.field_sint64_
20970    && field_sint32_ == other.field_sint32_
20971    && field_string_ == other.field_string_
20972    && field_bytes_ == other.field_bytes_;
20973 }
20974 
ParseFromArray(const void * raw,size_t size)20975 bool TestConfig_DummyFields::ParseFromArray(const void* raw, size_t size) {
20976   unknown_fields_.clear();
20977   bool packed_error = false;
20978 
20979   ::protozero::ProtoDecoder dec(raw, size);
20980   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
20981     if (field.id() < _has_field_.size()) {
20982       _has_field_.set(field.id());
20983     }
20984     switch (field.id()) {
20985       case 1 /* field_uint32 */:
20986         field.get(&field_uint32_);
20987         break;
20988       case 2 /* field_int32 */:
20989         field.get(&field_int32_);
20990         break;
20991       case 3 /* field_uint64 */:
20992         field.get(&field_uint64_);
20993         break;
20994       case 4 /* field_int64 */:
20995         field.get(&field_int64_);
20996         break;
20997       case 5 /* field_fixed64 */:
20998         field.get(&field_fixed64_);
20999         break;
21000       case 6 /* field_sfixed64 */:
21001         field.get(&field_sfixed64_);
21002         break;
21003       case 7 /* field_fixed32 */:
21004         field.get(&field_fixed32_);
21005         break;
21006       case 8 /* field_sfixed32 */:
21007         field.get(&field_sfixed32_);
21008         break;
21009       case 9 /* field_double */:
21010         field.get(&field_double_);
21011         break;
21012       case 10 /* field_float */:
21013         field.get(&field_float_);
21014         break;
21015       case 11 /* field_sint64 */:
21016         field.get_signed(&field_sint64_);
21017         break;
21018       case 12 /* field_sint32 */:
21019         field.get_signed(&field_sint32_);
21020         break;
21021       case 13 /* field_string */:
21022         field.get(&field_string_);
21023         break;
21024       case 14 /* field_bytes */:
21025         field.get(&field_bytes_);
21026         break;
21027       default:
21028         field.SerializeAndAppendTo(&unknown_fields_);
21029         break;
21030     }
21031   }
21032   return !packed_error && !dec.bytes_left();
21033 }
21034 
SerializeAsString() const21035 std::string TestConfig_DummyFields::SerializeAsString() const {
21036   ::protozero::HeapBuffered<::protozero::Message> msg;
21037   Serialize(msg.get());
21038   return msg.SerializeAsString();
21039 }
21040 
SerializeAsArray() const21041 std::vector<uint8_t> TestConfig_DummyFields::SerializeAsArray() const {
21042   ::protozero::HeapBuffered<::protozero::Message> msg;
21043   Serialize(msg.get());
21044   return msg.SerializeAsArray();
21045 }
21046 
Serialize(::protozero::Message * msg) const21047 void TestConfig_DummyFields::Serialize(::protozero::Message* msg) const {
21048   // Field 1: field_uint32
21049   if (_has_field_[1]) {
21050     msg->AppendVarInt(1, field_uint32_);
21051   }
21052 
21053   // Field 2: field_int32
21054   if (_has_field_[2]) {
21055     msg->AppendVarInt(2, field_int32_);
21056   }
21057 
21058   // Field 3: field_uint64
21059   if (_has_field_[3]) {
21060     msg->AppendVarInt(3, field_uint64_);
21061   }
21062 
21063   // Field 4: field_int64
21064   if (_has_field_[4]) {
21065     msg->AppendVarInt(4, field_int64_);
21066   }
21067 
21068   // Field 5: field_fixed64
21069   if (_has_field_[5]) {
21070     msg->AppendFixed(5, field_fixed64_);
21071   }
21072 
21073   // Field 6: field_sfixed64
21074   if (_has_field_[6]) {
21075     msg->AppendFixed(6, field_sfixed64_);
21076   }
21077 
21078   // Field 7: field_fixed32
21079   if (_has_field_[7]) {
21080     msg->AppendFixed(7, field_fixed32_);
21081   }
21082 
21083   // Field 8: field_sfixed32
21084   if (_has_field_[8]) {
21085     msg->AppendFixed(8, field_sfixed32_);
21086   }
21087 
21088   // Field 9: field_double
21089   if (_has_field_[9]) {
21090     msg->AppendFixed(9, field_double_);
21091   }
21092 
21093   // Field 10: field_float
21094   if (_has_field_[10]) {
21095     msg->AppendFixed(10, field_float_);
21096   }
21097 
21098   // Field 11: field_sint64
21099   if (_has_field_[11]) {
21100     msg->AppendSignedVarInt(11, field_sint64_);
21101   }
21102 
21103   // Field 12: field_sint32
21104   if (_has_field_[12]) {
21105     msg->AppendSignedVarInt(12, field_sint32_);
21106   }
21107 
21108   // Field 13: field_string
21109   if (_has_field_[13]) {
21110     msg->AppendString(13, field_string_);
21111   }
21112 
21113   // Field 14: field_bytes
21114   if (_has_field_[14]) {
21115     msg->AppendString(14, field_bytes_);
21116   }
21117 
21118   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
21119 }
21120 
21121 }  // namespace perfetto
21122 }  // namespace protos
21123 }  // namespace gen
21124 #if defined(__GNUC__) || defined(__clang__)
21125 #pragma GCC diagnostic pop
21126 #endif
21127 // gen_amalgamated begin source: gen/protos/perfetto/config/trace_config.gen.cc
21128 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
21129 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
21130 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
21131 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
21132 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
21133 #if defined(__GNUC__) || defined(__clang__)
21134 #pragma GCC diagnostic push
21135 #pragma GCC diagnostic ignored "-Wfloat-equal"
21136 #endif
21137 // gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.gen.h"
21138 // gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"
21139 // gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
21140 // gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"
21141 // gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
21142 // gen_amalgamated expanded: #include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
21143 // gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
21144 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/perf_event_config.gen.h"
21145 // gen_amalgamated expanded: #include "protos/perfetto/common/perf_events.gen.h"
21146 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/java_hprof_config.gen.h"
21147 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/heapprofd_config.gen.h"
21148 // gen_amalgamated expanded: #include "protos/perfetto/config/process_stats/process_stats_config.gen.h"
21149 // gen_amalgamated expanded: #include "protos/perfetto/config/power/android_power_config.gen.h"
21150 // gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
21151 // gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
21152 // gen_amalgamated expanded: #include "protos/perfetto/config/inode_file/inode_file_config.gen.h"
21153 // gen_amalgamated expanded: #include "protos/perfetto/config/gpu/vulkan_memory_config.gen.h"
21154 // gen_amalgamated expanded: #include "protos/perfetto/config/gpu/gpu_counter_config.gen.h"
21155 // gen_amalgamated expanded: #include "protos/perfetto/config/ftrace/ftrace_config.gen.h"
21156 // gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
21157 // gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_config.gen.h"
21158 // gen_amalgamated expanded: #include "protos/perfetto/config/android/android_polled_state_config.gen.h"
21159 // gen_amalgamated expanded: #include "protos/perfetto/config/android/android_log_config.gen.h"
21160 // gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
21161 
21162 namespace perfetto {
21163 namespace protos {
21164 namespace gen {
21165 
21166 TraceConfig::TraceConfig() = default;
21167 TraceConfig::~TraceConfig() = default;
21168 TraceConfig::TraceConfig(const TraceConfig&) = default;
21169 TraceConfig& TraceConfig::operator=(const TraceConfig&) = default;
21170 TraceConfig::TraceConfig(TraceConfig&&) noexcept = default;
21171 TraceConfig& TraceConfig::operator=(TraceConfig&&) = default;
21172 
operator ==(const TraceConfig & other) const21173 bool TraceConfig::operator==(const TraceConfig& other) const {
21174   return unknown_fields_ == other.unknown_fields_
21175    && buffers_ == other.buffers_
21176    && data_sources_ == other.data_sources_
21177    && builtin_data_sources_ == other.builtin_data_sources_
21178    && duration_ms_ == other.duration_ms_
21179    && enable_extra_guardrails_ == other.enable_extra_guardrails_
21180    && lockdown_mode_ == other.lockdown_mode_
21181    && producers_ == other.producers_
21182    && statsd_metadata_ == other.statsd_metadata_
21183    && write_into_file_ == other.write_into_file_
21184    && output_path_ == other.output_path_
21185    && file_write_period_ms_ == other.file_write_period_ms_
21186    && max_file_size_bytes_ == other.max_file_size_bytes_
21187    && guardrail_overrides_ == other.guardrail_overrides_
21188    && deferred_start_ == other.deferred_start_
21189    && flush_period_ms_ == other.flush_period_ms_
21190    && flush_timeout_ms_ == other.flush_timeout_ms_
21191    && data_source_stop_timeout_ms_ == other.data_source_stop_timeout_ms_
21192    && notify_traceur_ == other.notify_traceur_
21193    && bugreport_score_ == other.bugreport_score_
21194    && trigger_config_ == other.trigger_config_
21195    && activate_triggers_ == other.activate_triggers_
21196    && incremental_state_config_ == other.incremental_state_config_
21197    && allow_user_build_tracing_ == other.allow_user_build_tracing_
21198    && unique_session_name_ == other.unique_session_name_
21199    && compression_type_ == other.compression_type_
21200    && incident_report_config_ == other.incident_report_config_
21201    && statsd_logging_ == other.statsd_logging_
21202    && trace_uuid_msb_ == other.trace_uuid_msb_
21203    && trace_uuid_lsb_ == other.trace_uuid_lsb_
21204    && trace_filter_ == other.trace_filter_;
21205 }
21206 
buffers_size() const21207 int TraceConfig::buffers_size() const { return static_cast<int>(buffers_.size()); }
clear_buffers()21208 void TraceConfig::clear_buffers() { buffers_.clear(); }
add_buffers()21209 TraceConfig_BufferConfig* TraceConfig::add_buffers() { buffers_.emplace_back(); return &buffers_.back(); }
data_sources_size() const21210 int TraceConfig::data_sources_size() const { return static_cast<int>(data_sources_.size()); }
clear_data_sources()21211 void TraceConfig::clear_data_sources() { data_sources_.clear(); }
add_data_sources()21212 TraceConfig_DataSource* TraceConfig::add_data_sources() { data_sources_.emplace_back(); return &data_sources_.back(); }
producers_size() const21213 int TraceConfig::producers_size() const { return static_cast<int>(producers_.size()); }
clear_producers()21214 void TraceConfig::clear_producers() { producers_.clear(); }
add_producers()21215 TraceConfig_ProducerConfig* TraceConfig::add_producers() { producers_.emplace_back(); return &producers_.back(); }
ParseFromArray(const void * raw,size_t size)21216 bool TraceConfig::ParseFromArray(const void* raw, size_t size) {
21217   buffers_.clear();
21218   data_sources_.clear();
21219   producers_.clear();
21220   activate_triggers_.clear();
21221   unknown_fields_.clear();
21222   bool packed_error = false;
21223 
21224   ::protozero::ProtoDecoder dec(raw, size);
21225   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
21226     if (field.id() < _has_field_.size()) {
21227       _has_field_.set(field.id());
21228     }
21229     switch (field.id()) {
21230       case 1 /* buffers */:
21231         buffers_.emplace_back();
21232         buffers_.back().ParseFromArray(field.data(), field.size());
21233         break;
21234       case 2 /* data_sources */:
21235         data_sources_.emplace_back();
21236         data_sources_.back().ParseFromArray(field.data(), field.size());
21237         break;
21238       case 20 /* builtin_data_sources */:
21239         (*builtin_data_sources_).ParseFromArray(field.data(), field.size());
21240         break;
21241       case 3 /* duration_ms */:
21242         field.get(&duration_ms_);
21243         break;
21244       case 4 /* enable_extra_guardrails */:
21245         field.get(&enable_extra_guardrails_);
21246         break;
21247       case 5 /* lockdown_mode */:
21248         field.get(&lockdown_mode_);
21249         break;
21250       case 6 /* producers */:
21251         producers_.emplace_back();
21252         producers_.back().ParseFromArray(field.data(), field.size());
21253         break;
21254       case 7 /* statsd_metadata */:
21255         (*statsd_metadata_).ParseFromArray(field.data(), field.size());
21256         break;
21257       case 8 /* write_into_file */:
21258         field.get(&write_into_file_);
21259         break;
21260       case 29 /* output_path */:
21261         field.get(&output_path_);
21262         break;
21263       case 9 /* file_write_period_ms */:
21264         field.get(&file_write_period_ms_);
21265         break;
21266       case 10 /* max_file_size_bytes */:
21267         field.get(&max_file_size_bytes_);
21268         break;
21269       case 11 /* guardrail_overrides */:
21270         (*guardrail_overrides_).ParseFromArray(field.data(), field.size());
21271         break;
21272       case 12 /* deferred_start */:
21273         field.get(&deferred_start_);
21274         break;
21275       case 13 /* flush_period_ms */:
21276         field.get(&flush_period_ms_);
21277         break;
21278       case 14 /* flush_timeout_ms */:
21279         field.get(&flush_timeout_ms_);
21280         break;
21281       case 23 /* data_source_stop_timeout_ms */:
21282         field.get(&data_source_stop_timeout_ms_);
21283         break;
21284       case 16 /* notify_traceur */:
21285         field.get(&notify_traceur_);
21286         break;
21287       case 30 /* bugreport_score */:
21288         field.get(&bugreport_score_);
21289         break;
21290       case 17 /* trigger_config */:
21291         (*trigger_config_).ParseFromArray(field.data(), field.size());
21292         break;
21293       case 18 /* activate_triggers */:
21294         activate_triggers_.emplace_back();
21295         field.get(&activate_triggers_.back());
21296         break;
21297       case 21 /* incremental_state_config */:
21298         (*incremental_state_config_).ParseFromArray(field.data(), field.size());
21299         break;
21300       case 19 /* allow_user_build_tracing */:
21301         field.get(&allow_user_build_tracing_);
21302         break;
21303       case 22 /* unique_session_name */:
21304         field.get(&unique_session_name_);
21305         break;
21306       case 24 /* compression_type */:
21307         field.get(&compression_type_);
21308         break;
21309       case 25 /* incident_report_config */:
21310         (*incident_report_config_).ParseFromArray(field.data(), field.size());
21311         break;
21312       case 31 /* statsd_logging */:
21313         field.get(&statsd_logging_);
21314         break;
21315       case 27 /* trace_uuid_msb */:
21316         field.get(&trace_uuid_msb_);
21317         break;
21318       case 28 /* trace_uuid_lsb */:
21319         field.get(&trace_uuid_lsb_);
21320         break;
21321       case 32 /* trace_filter */:
21322         (*trace_filter_).ParseFromArray(field.data(), field.size());
21323         break;
21324       default:
21325         field.SerializeAndAppendTo(&unknown_fields_);
21326         break;
21327     }
21328   }
21329   return !packed_error && !dec.bytes_left();
21330 }
21331 
SerializeAsString() const21332 std::string TraceConfig::SerializeAsString() const {
21333   ::protozero::HeapBuffered<::protozero::Message> msg;
21334   Serialize(msg.get());
21335   return msg.SerializeAsString();
21336 }
21337 
SerializeAsArray() const21338 std::vector<uint8_t> TraceConfig::SerializeAsArray() const {
21339   ::protozero::HeapBuffered<::protozero::Message> msg;
21340   Serialize(msg.get());
21341   return msg.SerializeAsArray();
21342 }
21343 
Serialize(::protozero::Message * msg) const21344 void TraceConfig::Serialize(::protozero::Message* msg) const {
21345   // Field 1: buffers
21346   for (auto& it : buffers_) {
21347     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
21348   }
21349 
21350   // Field 2: data_sources
21351   for (auto& it : data_sources_) {
21352     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
21353   }
21354 
21355   // Field 20: builtin_data_sources
21356   if (_has_field_[20]) {
21357     (*builtin_data_sources_).Serialize(msg->BeginNestedMessage<::protozero::Message>(20));
21358   }
21359 
21360   // Field 3: duration_ms
21361   if (_has_field_[3]) {
21362     msg->AppendVarInt(3, duration_ms_);
21363   }
21364 
21365   // Field 4: enable_extra_guardrails
21366   if (_has_field_[4]) {
21367     msg->AppendTinyVarInt(4, enable_extra_guardrails_);
21368   }
21369 
21370   // Field 5: lockdown_mode
21371   if (_has_field_[5]) {
21372     msg->AppendVarInt(5, lockdown_mode_);
21373   }
21374 
21375   // Field 6: producers
21376   for (auto& it : producers_) {
21377     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
21378   }
21379 
21380   // Field 7: statsd_metadata
21381   if (_has_field_[7]) {
21382     (*statsd_metadata_).Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
21383   }
21384 
21385   // Field 8: write_into_file
21386   if (_has_field_[8]) {
21387     msg->AppendTinyVarInt(8, write_into_file_);
21388   }
21389 
21390   // Field 29: output_path
21391   if (_has_field_[29]) {
21392     msg->AppendString(29, output_path_);
21393   }
21394 
21395   // Field 9: file_write_period_ms
21396   if (_has_field_[9]) {
21397     msg->AppendVarInt(9, file_write_period_ms_);
21398   }
21399 
21400   // Field 10: max_file_size_bytes
21401   if (_has_field_[10]) {
21402     msg->AppendVarInt(10, max_file_size_bytes_);
21403   }
21404 
21405   // Field 11: guardrail_overrides
21406   if (_has_field_[11]) {
21407     (*guardrail_overrides_).Serialize(msg->BeginNestedMessage<::protozero::Message>(11));
21408   }
21409 
21410   // Field 12: deferred_start
21411   if (_has_field_[12]) {
21412     msg->AppendTinyVarInt(12, deferred_start_);
21413   }
21414 
21415   // Field 13: flush_period_ms
21416   if (_has_field_[13]) {
21417     msg->AppendVarInt(13, flush_period_ms_);
21418   }
21419 
21420   // Field 14: flush_timeout_ms
21421   if (_has_field_[14]) {
21422     msg->AppendVarInt(14, flush_timeout_ms_);
21423   }
21424 
21425   // Field 23: data_source_stop_timeout_ms
21426   if (_has_field_[23]) {
21427     msg->AppendVarInt(23, data_source_stop_timeout_ms_);
21428   }
21429 
21430   // Field 16: notify_traceur
21431   if (_has_field_[16]) {
21432     msg->AppendTinyVarInt(16, notify_traceur_);
21433   }
21434 
21435   // Field 30: bugreport_score
21436   if (_has_field_[30]) {
21437     msg->AppendVarInt(30, bugreport_score_);
21438   }
21439 
21440   // Field 17: trigger_config
21441   if (_has_field_[17]) {
21442     (*trigger_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(17));
21443   }
21444 
21445   // Field 18: activate_triggers
21446   for (auto& it : activate_triggers_) {
21447     msg->AppendString(18, it);
21448   }
21449 
21450   // Field 21: incremental_state_config
21451   if (_has_field_[21]) {
21452     (*incremental_state_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(21));
21453   }
21454 
21455   // Field 19: allow_user_build_tracing
21456   if (_has_field_[19]) {
21457     msg->AppendTinyVarInt(19, allow_user_build_tracing_);
21458   }
21459 
21460   // Field 22: unique_session_name
21461   if (_has_field_[22]) {
21462     msg->AppendString(22, unique_session_name_);
21463   }
21464 
21465   // Field 24: compression_type
21466   if (_has_field_[24]) {
21467     msg->AppendVarInt(24, compression_type_);
21468   }
21469 
21470   // Field 25: incident_report_config
21471   if (_has_field_[25]) {
21472     (*incident_report_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(25));
21473   }
21474 
21475   // Field 31: statsd_logging
21476   if (_has_field_[31]) {
21477     msg->AppendVarInt(31, statsd_logging_);
21478   }
21479 
21480   // Field 27: trace_uuid_msb
21481   if (_has_field_[27]) {
21482     msg->AppendVarInt(27, trace_uuid_msb_);
21483   }
21484 
21485   // Field 28: trace_uuid_lsb
21486   if (_has_field_[28]) {
21487     msg->AppendVarInt(28, trace_uuid_lsb_);
21488   }
21489 
21490   // Field 32: trace_filter
21491   if (_has_field_[32]) {
21492     (*trace_filter_).Serialize(msg->BeginNestedMessage<::protozero::Message>(32));
21493   }
21494 
21495   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
21496 }
21497 
21498 
21499 TraceConfig_TraceFilter::TraceConfig_TraceFilter() = default;
21500 TraceConfig_TraceFilter::~TraceConfig_TraceFilter() = default;
21501 TraceConfig_TraceFilter::TraceConfig_TraceFilter(const TraceConfig_TraceFilter&) = default;
21502 TraceConfig_TraceFilter& TraceConfig_TraceFilter::operator=(const TraceConfig_TraceFilter&) = default;
21503 TraceConfig_TraceFilter::TraceConfig_TraceFilter(TraceConfig_TraceFilter&&) noexcept = default;
21504 TraceConfig_TraceFilter& TraceConfig_TraceFilter::operator=(TraceConfig_TraceFilter&&) = default;
21505 
operator ==(const TraceConfig_TraceFilter & other) const21506 bool TraceConfig_TraceFilter::operator==(const TraceConfig_TraceFilter& other) const {
21507   return unknown_fields_ == other.unknown_fields_
21508    && bytecode_ == other.bytecode_;
21509 }
21510 
ParseFromArray(const void * raw,size_t size)21511 bool TraceConfig_TraceFilter::ParseFromArray(const void* raw, size_t size) {
21512   unknown_fields_.clear();
21513   bool packed_error = false;
21514 
21515   ::protozero::ProtoDecoder dec(raw, size);
21516   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
21517     if (field.id() < _has_field_.size()) {
21518       _has_field_.set(field.id());
21519     }
21520     switch (field.id()) {
21521       case 1 /* bytecode */:
21522         field.get(&bytecode_);
21523         break;
21524       default:
21525         field.SerializeAndAppendTo(&unknown_fields_);
21526         break;
21527     }
21528   }
21529   return !packed_error && !dec.bytes_left();
21530 }
21531 
SerializeAsString() const21532 std::string TraceConfig_TraceFilter::SerializeAsString() const {
21533   ::protozero::HeapBuffered<::protozero::Message> msg;
21534   Serialize(msg.get());
21535   return msg.SerializeAsString();
21536 }
21537 
SerializeAsArray() const21538 std::vector<uint8_t> TraceConfig_TraceFilter::SerializeAsArray() const {
21539   ::protozero::HeapBuffered<::protozero::Message> msg;
21540   Serialize(msg.get());
21541   return msg.SerializeAsArray();
21542 }
21543 
Serialize(::protozero::Message * msg) const21544 void TraceConfig_TraceFilter::Serialize(::protozero::Message* msg) const {
21545   // Field 1: bytecode
21546   if (_has_field_[1]) {
21547     msg->AppendString(1, bytecode_);
21548   }
21549 
21550   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
21551 }
21552 
21553 
21554 TraceConfig_IncidentReportConfig::TraceConfig_IncidentReportConfig() = default;
21555 TraceConfig_IncidentReportConfig::~TraceConfig_IncidentReportConfig() = default;
21556 TraceConfig_IncidentReportConfig::TraceConfig_IncidentReportConfig(const TraceConfig_IncidentReportConfig&) = default;
21557 TraceConfig_IncidentReportConfig& TraceConfig_IncidentReportConfig::operator=(const TraceConfig_IncidentReportConfig&) = default;
21558 TraceConfig_IncidentReportConfig::TraceConfig_IncidentReportConfig(TraceConfig_IncidentReportConfig&&) noexcept = default;
21559 TraceConfig_IncidentReportConfig& TraceConfig_IncidentReportConfig::operator=(TraceConfig_IncidentReportConfig&&) = default;
21560 
operator ==(const TraceConfig_IncidentReportConfig & other) const21561 bool TraceConfig_IncidentReportConfig::operator==(const TraceConfig_IncidentReportConfig& other) const {
21562   return unknown_fields_ == other.unknown_fields_
21563    && destination_package_ == other.destination_package_
21564    && destination_class_ == other.destination_class_
21565    && privacy_level_ == other.privacy_level_
21566    && skip_incidentd_ == other.skip_incidentd_
21567    && skip_dropbox_ == other.skip_dropbox_;
21568 }
21569 
ParseFromArray(const void * raw,size_t size)21570 bool TraceConfig_IncidentReportConfig::ParseFromArray(const void* raw, size_t size) {
21571   unknown_fields_.clear();
21572   bool packed_error = false;
21573 
21574   ::protozero::ProtoDecoder dec(raw, size);
21575   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
21576     if (field.id() < _has_field_.size()) {
21577       _has_field_.set(field.id());
21578     }
21579     switch (field.id()) {
21580       case 1 /* destination_package */:
21581         field.get(&destination_package_);
21582         break;
21583       case 2 /* destination_class */:
21584         field.get(&destination_class_);
21585         break;
21586       case 3 /* privacy_level */:
21587         field.get(&privacy_level_);
21588         break;
21589       case 5 /* skip_incidentd */:
21590         field.get(&skip_incidentd_);
21591         break;
21592       case 4 /* skip_dropbox */:
21593         field.get(&skip_dropbox_);
21594         break;
21595       default:
21596         field.SerializeAndAppendTo(&unknown_fields_);
21597         break;
21598     }
21599   }
21600   return !packed_error && !dec.bytes_left();
21601 }
21602 
SerializeAsString() const21603 std::string TraceConfig_IncidentReportConfig::SerializeAsString() const {
21604   ::protozero::HeapBuffered<::protozero::Message> msg;
21605   Serialize(msg.get());
21606   return msg.SerializeAsString();
21607 }
21608 
SerializeAsArray() const21609 std::vector<uint8_t> TraceConfig_IncidentReportConfig::SerializeAsArray() const {
21610   ::protozero::HeapBuffered<::protozero::Message> msg;
21611   Serialize(msg.get());
21612   return msg.SerializeAsArray();
21613 }
21614 
Serialize(::protozero::Message * msg) const21615 void TraceConfig_IncidentReportConfig::Serialize(::protozero::Message* msg) const {
21616   // Field 1: destination_package
21617   if (_has_field_[1]) {
21618     msg->AppendString(1, destination_package_);
21619   }
21620 
21621   // Field 2: destination_class
21622   if (_has_field_[2]) {
21623     msg->AppendString(2, destination_class_);
21624   }
21625 
21626   // Field 3: privacy_level
21627   if (_has_field_[3]) {
21628     msg->AppendVarInt(3, privacy_level_);
21629   }
21630 
21631   // Field 5: skip_incidentd
21632   if (_has_field_[5]) {
21633     msg->AppendTinyVarInt(5, skip_incidentd_);
21634   }
21635 
21636   // Field 4: skip_dropbox
21637   if (_has_field_[4]) {
21638     msg->AppendTinyVarInt(4, skip_dropbox_);
21639   }
21640 
21641   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
21642 }
21643 
21644 
21645 TraceConfig_IncrementalStateConfig::TraceConfig_IncrementalStateConfig() = default;
21646 TraceConfig_IncrementalStateConfig::~TraceConfig_IncrementalStateConfig() = default;
21647 TraceConfig_IncrementalStateConfig::TraceConfig_IncrementalStateConfig(const TraceConfig_IncrementalStateConfig&) = default;
21648 TraceConfig_IncrementalStateConfig& TraceConfig_IncrementalStateConfig::operator=(const TraceConfig_IncrementalStateConfig&) = default;
21649 TraceConfig_IncrementalStateConfig::TraceConfig_IncrementalStateConfig(TraceConfig_IncrementalStateConfig&&) noexcept = default;
21650 TraceConfig_IncrementalStateConfig& TraceConfig_IncrementalStateConfig::operator=(TraceConfig_IncrementalStateConfig&&) = default;
21651 
operator ==(const TraceConfig_IncrementalStateConfig & other) const21652 bool TraceConfig_IncrementalStateConfig::operator==(const TraceConfig_IncrementalStateConfig& other) const {
21653   return unknown_fields_ == other.unknown_fields_
21654    && clear_period_ms_ == other.clear_period_ms_;
21655 }
21656 
ParseFromArray(const void * raw,size_t size)21657 bool TraceConfig_IncrementalStateConfig::ParseFromArray(const void* raw, size_t size) {
21658   unknown_fields_.clear();
21659   bool packed_error = false;
21660 
21661   ::protozero::ProtoDecoder dec(raw, size);
21662   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
21663     if (field.id() < _has_field_.size()) {
21664       _has_field_.set(field.id());
21665     }
21666     switch (field.id()) {
21667       case 1 /* clear_period_ms */:
21668         field.get(&clear_period_ms_);
21669         break;
21670       default:
21671         field.SerializeAndAppendTo(&unknown_fields_);
21672         break;
21673     }
21674   }
21675   return !packed_error && !dec.bytes_left();
21676 }
21677 
SerializeAsString() const21678 std::string TraceConfig_IncrementalStateConfig::SerializeAsString() const {
21679   ::protozero::HeapBuffered<::protozero::Message> msg;
21680   Serialize(msg.get());
21681   return msg.SerializeAsString();
21682 }
21683 
SerializeAsArray() const21684 std::vector<uint8_t> TraceConfig_IncrementalStateConfig::SerializeAsArray() const {
21685   ::protozero::HeapBuffered<::protozero::Message> msg;
21686   Serialize(msg.get());
21687   return msg.SerializeAsArray();
21688 }
21689 
Serialize(::protozero::Message * msg) const21690 void TraceConfig_IncrementalStateConfig::Serialize(::protozero::Message* msg) const {
21691   // Field 1: clear_period_ms
21692   if (_has_field_[1]) {
21693     msg->AppendVarInt(1, clear_period_ms_);
21694   }
21695 
21696   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
21697 }
21698 
21699 
21700 TraceConfig_TriggerConfig::TraceConfig_TriggerConfig() = default;
21701 TraceConfig_TriggerConfig::~TraceConfig_TriggerConfig() = default;
21702 TraceConfig_TriggerConfig::TraceConfig_TriggerConfig(const TraceConfig_TriggerConfig&) = default;
21703 TraceConfig_TriggerConfig& TraceConfig_TriggerConfig::operator=(const TraceConfig_TriggerConfig&) = default;
21704 TraceConfig_TriggerConfig::TraceConfig_TriggerConfig(TraceConfig_TriggerConfig&&) noexcept = default;
21705 TraceConfig_TriggerConfig& TraceConfig_TriggerConfig::operator=(TraceConfig_TriggerConfig&&) = default;
21706 
operator ==(const TraceConfig_TriggerConfig & other) const21707 bool TraceConfig_TriggerConfig::operator==(const TraceConfig_TriggerConfig& other) const {
21708   return unknown_fields_ == other.unknown_fields_
21709    && trigger_mode_ == other.trigger_mode_
21710    && triggers_ == other.triggers_
21711    && trigger_timeout_ms_ == other.trigger_timeout_ms_;
21712 }
21713 
triggers_size() const21714 int TraceConfig_TriggerConfig::triggers_size() const { return static_cast<int>(triggers_.size()); }
clear_triggers()21715 void TraceConfig_TriggerConfig::clear_triggers() { triggers_.clear(); }
add_triggers()21716 TraceConfig_TriggerConfig_Trigger* TraceConfig_TriggerConfig::add_triggers() { triggers_.emplace_back(); return &triggers_.back(); }
ParseFromArray(const void * raw,size_t size)21717 bool TraceConfig_TriggerConfig::ParseFromArray(const void* raw, size_t size) {
21718   triggers_.clear();
21719   unknown_fields_.clear();
21720   bool packed_error = false;
21721 
21722   ::protozero::ProtoDecoder dec(raw, size);
21723   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
21724     if (field.id() < _has_field_.size()) {
21725       _has_field_.set(field.id());
21726     }
21727     switch (field.id()) {
21728       case 1 /* trigger_mode */:
21729         field.get(&trigger_mode_);
21730         break;
21731       case 2 /* triggers */:
21732         triggers_.emplace_back();
21733         triggers_.back().ParseFromArray(field.data(), field.size());
21734         break;
21735       case 3 /* trigger_timeout_ms */:
21736         field.get(&trigger_timeout_ms_);
21737         break;
21738       default:
21739         field.SerializeAndAppendTo(&unknown_fields_);
21740         break;
21741     }
21742   }
21743   return !packed_error && !dec.bytes_left();
21744 }
21745 
SerializeAsString() const21746 std::string TraceConfig_TriggerConfig::SerializeAsString() const {
21747   ::protozero::HeapBuffered<::protozero::Message> msg;
21748   Serialize(msg.get());
21749   return msg.SerializeAsString();
21750 }
21751 
SerializeAsArray() const21752 std::vector<uint8_t> TraceConfig_TriggerConfig::SerializeAsArray() const {
21753   ::protozero::HeapBuffered<::protozero::Message> msg;
21754   Serialize(msg.get());
21755   return msg.SerializeAsArray();
21756 }
21757 
Serialize(::protozero::Message * msg) const21758 void TraceConfig_TriggerConfig::Serialize(::protozero::Message* msg) const {
21759   // Field 1: trigger_mode
21760   if (_has_field_[1]) {
21761     msg->AppendVarInt(1, trigger_mode_);
21762   }
21763 
21764   // Field 2: triggers
21765   for (auto& it : triggers_) {
21766     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
21767   }
21768 
21769   // Field 3: trigger_timeout_ms
21770   if (_has_field_[3]) {
21771     msg->AppendVarInt(3, trigger_timeout_ms_);
21772   }
21773 
21774   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
21775 }
21776 
21777 
21778 TraceConfig_TriggerConfig_Trigger::TraceConfig_TriggerConfig_Trigger() = default;
21779 TraceConfig_TriggerConfig_Trigger::~TraceConfig_TriggerConfig_Trigger() = default;
21780 TraceConfig_TriggerConfig_Trigger::TraceConfig_TriggerConfig_Trigger(const TraceConfig_TriggerConfig_Trigger&) = default;
21781 TraceConfig_TriggerConfig_Trigger& TraceConfig_TriggerConfig_Trigger::operator=(const TraceConfig_TriggerConfig_Trigger&) = default;
21782 TraceConfig_TriggerConfig_Trigger::TraceConfig_TriggerConfig_Trigger(TraceConfig_TriggerConfig_Trigger&&) noexcept = default;
21783 TraceConfig_TriggerConfig_Trigger& TraceConfig_TriggerConfig_Trigger::operator=(TraceConfig_TriggerConfig_Trigger&&) = default;
21784 
operator ==(const TraceConfig_TriggerConfig_Trigger & other) const21785 bool TraceConfig_TriggerConfig_Trigger::operator==(const TraceConfig_TriggerConfig_Trigger& other) const {
21786   return unknown_fields_ == other.unknown_fields_
21787    && name_ == other.name_
21788    && producer_name_regex_ == other.producer_name_regex_
21789    && stop_delay_ms_ == other.stop_delay_ms_
21790    && max_per_24_h_ == other.max_per_24_h_
21791    && skip_probability_ == other.skip_probability_;
21792 }
21793 
ParseFromArray(const void * raw,size_t size)21794 bool TraceConfig_TriggerConfig_Trigger::ParseFromArray(const void* raw, size_t size) {
21795   unknown_fields_.clear();
21796   bool packed_error = false;
21797 
21798   ::protozero::ProtoDecoder dec(raw, size);
21799   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
21800     if (field.id() < _has_field_.size()) {
21801       _has_field_.set(field.id());
21802     }
21803     switch (field.id()) {
21804       case 1 /* name */:
21805         field.get(&name_);
21806         break;
21807       case 2 /* producer_name_regex */:
21808         field.get(&producer_name_regex_);
21809         break;
21810       case 3 /* stop_delay_ms */:
21811         field.get(&stop_delay_ms_);
21812         break;
21813       case 4 /* max_per_24_h */:
21814         field.get(&max_per_24_h_);
21815         break;
21816       case 5 /* skip_probability */:
21817         field.get(&skip_probability_);
21818         break;
21819       default:
21820         field.SerializeAndAppendTo(&unknown_fields_);
21821         break;
21822     }
21823   }
21824   return !packed_error && !dec.bytes_left();
21825 }
21826 
SerializeAsString() const21827 std::string TraceConfig_TriggerConfig_Trigger::SerializeAsString() const {
21828   ::protozero::HeapBuffered<::protozero::Message> msg;
21829   Serialize(msg.get());
21830   return msg.SerializeAsString();
21831 }
21832 
SerializeAsArray() const21833 std::vector<uint8_t> TraceConfig_TriggerConfig_Trigger::SerializeAsArray() const {
21834   ::protozero::HeapBuffered<::protozero::Message> msg;
21835   Serialize(msg.get());
21836   return msg.SerializeAsArray();
21837 }
21838 
Serialize(::protozero::Message * msg) const21839 void TraceConfig_TriggerConfig_Trigger::Serialize(::protozero::Message* msg) const {
21840   // Field 1: name
21841   if (_has_field_[1]) {
21842     msg->AppendString(1, name_);
21843   }
21844 
21845   // Field 2: producer_name_regex
21846   if (_has_field_[2]) {
21847     msg->AppendString(2, producer_name_regex_);
21848   }
21849 
21850   // Field 3: stop_delay_ms
21851   if (_has_field_[3]) {
21852     msg->AppendVarInt(3, stop_delay_ms_);
21853   }
21854 
21855   // Field 4: max_per_24_h
21856   if (_has_field_[4]) {
21857     msg->AppendVarInt(4, max_per_24_h_);
21858   }
21859 
21860   // Field 5: skip_probability
21861   if (_has_field_[5]) {
21862     msg->AppendFixed(5, skip_probability_);
21863   }
21864 
21865   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
21866 }
21867 
21868 
21869 TraceConfig_GuardrailOverrides::TraceConfig_GuardrailOverrides() = default;
21870 TraceConfig_GuardrailOverrides::~TraceConfig_GuardrailOverrides() = default;
21871 TraceConfig_GuardrailOverrides::TraceConfig_GuardrailOverrides(const TraceConfig_GuardrailOverrides&) = default;
21872 TraceConfig_GuardrailOverrides& TraceConfig_GuardrailOverrides::operator=(const TraceConfig_GuardrailOverrides&) = default;
21873 TraceConfig_GuardrailOverrides::TraceConfig_GuardrailOverrides(TraceConfig_GuardrailOverrides&&) noexcept = default;
21874 TraceConfig_GuardrailOverrides& TraceConfig_GuardrailOverrides::operator=(TraceConfig_GuardrailOverrides&&) = default;
21875 
operator ==(const TraceConfig_GuardrailOverrides & other) const21876 bool TraceConfig_GuardrailOverrides::operator==(const TraceConfig_GuardrailOverrides& other) const {
21877   return unknown_fields_ == other.unknown_fields_
21878    && max_upload_per_day_bytes_ == other.max_upload_per_day_bytes_;
21879 }
21880 
ParseFromArray(const void * raw,size_t size)21881 bool TraceConfig_GuardrailOverrides::ParseFromArray(const void* raw, size_t size) {
21882   unknown_fields_.clear();
21883   bool packed_error = false;
21884 
21885   ::protozero::ProtoDecoder dec(raw, size);
21886   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
21887     if (field.id() < _has_field_.size()) {
21888       _has_field_.set(field.id());
21889     }
21890     switch (field.id()) {
21891       case 1 /* max_upload_per_day_bytes */:
21892         field.get(&max_upload_per_day_bytes_);
21893         break;
21894       default:
21895         field.SerializeAndAppendTo(&unknown_fields_);
21896         break;
21897     }
21898   }
21899   return !packed_error && !dec.bytes_left();
21900 }
21901 
SerializeAsString() const21902 std::string TraceConfig_GuardrailOverrides::SerializeAsString() const {
21903   ::protozero::HeapBuffered<::protozero::Message> msg;
21904   Serialize(msg.get());
21905   return msg.SerializeAsString();
21906 }
21907 
SerializeAsArray() const21908 std::vector<uint8_t> TraceConfig_GuardrailOverrides::SerializeAsArray() const {
21909   ::protozero::HeapBuffered<::protozero::Message> msg;
21910   Serialize(msg.get());
21911   return msg.SerializeAsArray();
21912 }
21913 
Serialize(::protozero::Message * msg) const21914 void TraceConfig_GuardrailOverrides::Serialize(::protozero::Message* msg) const {
21915   // Field 1: max_upload_per_day_bytes
21916   if (_has_field_[1]) {
21917     msg->AppendVarInt(1, max_upload_per_day_bytes_);
21918   }
21919 
21920   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
21921 }
21922 
21923 
21924 TraceConfig_StatsdMetadata::TraceConfig_StatsdMetadata() = default;
21925 TraceConfig_StatsdMetadata::~TraceConfig_StatsdMetadata() = default;
21926 TraceConfig_StatsdMetadata::TraceConfig_StatsdMetadata(const TraceConfig_StatsdMetadata&) = default;
21927 TraceConfig_StatsdMetadata& TraceConfig_StatsdMetadata::operator=(const TraceConfig_StatsdMetadata&) = default;
21928 TraceConfig_StatsdMetadata::TraceConfig_StatsdMetadata(TraceConfig_StatsdMetadata&&) noexcept = default;
21929 TraceConfig_StatsdMetadata& TraceConfig_StatsdMetadata::operator=(TraceConfig_StatsdMetadata&&) = default;
21930 
operator ==(const TraceConfig_StatsdMetadata & other) const21931 bool TraceConfig_StatsdMetadata::operator==(const TraceConfig_StatsdMetadata& other) const {
21932   return unknown_fields_ == other.unknown_fields_
21933    && triggering_alert_id_ == other.triggering_alert_id_
21934    && triggering_config_uid_ == other.triggering_config_uid_
21935    && triggering_config_id_ == other.triggering_config_id_
21936    && triggering_subscription_id_ == other.triggering_subscription_id_;
21937 }
21938 
ParseFromArray(const void * raw,size_t size)21939 bool TraceConfig_StatsdMetadata::ParseFromArray(const void* raw, size_t size) {
21940   unknown_fields_.clear();
21941   bool packed_error = false;
21942 
21943   ::protozero::ProtoDecoder dec(raw, size);
21944   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
21945     if (field.id() < _has_field_.size()) {
21946       _has_field_.set(field.id());
21947     }
21948     switch (field.id()) {
21949       case 1 /* triggering_alert_id */:
21950         field.get(&triggering_alert_id_);
21951         break;
21952       case 2 /* triggering_config_uid */:
21953         field.get(&triggering_config_uid_);
21954         break;
21955       case 3 /* triggering_config_id */:
21956         field.get(&triggering_config_id_);
21957         break;
21958       case 4 /* triggering_subscription_id */:
21959         field.get(&triggering_subscription_id_);
21960         break;
21961       default:
21962         field.SerializeAndAppendTo(&unknown_fields_);
21963         break;
21964     }
21965   }
21966   return !packed_error && !dec.bytes_left();
21967 }
21968 
SerializeAsString() const21969 std::string TraceConfig_StatsdMetadata::SerializeAsString() const {
21970   ::protozero::HeapBuffered<::protozero::Message> msg;
21971   Serialize(msg.get());
21972   return msg.SerializeAsString();
21973 }
21974 
SerializeAsArray() const21975 std::vector<uint8_t> TraceConfig_StatsdMetadata::SerializeAsArray() const {
21976   ::protozero::HeapBuffered<::protozero::Message> msg;
21977   Serialize(msg.get());
21978   return msg.SerializeAsArray();
21979 }
21980 
Serialize(::protozero::Message * msg) const21981 void TraceConfig_StatsdMetadata::Serialize(::protozero::Message* msg) const {
21982   // Field 1: triggering_alert_id
21983   if (_has_field_[1]) {
21984     msg->AppendVarInt(1, triggering_alert_id_);
21985   }
21986 
21987   // Field 2: triggering_config_uid
21988   if (_has_field_[2]) {
21989     msg->AppendVarInt(2, triggering_config_uid_);
21990   }
21991 
21992   // Field 3: triggering_config_id
21993   if (_has_field_[3]) {
21994     msg->AppendVarInt(3, triggering_config_id_);
21995   }
21996 
21997   // Field 4: triggering_subscription_id
21998   if (_has_field_[4]) {
21999     msg->AppendVarInt(4, triggering_subscription_id_);
22000   }
22001 
22002   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
22003 }
22004 
22005 
22006 TraceConfig_ProducerConfig::TraceConfig_ProducerConfig() = default;
22007 TraceConfig_ProducerConfig::~TraceConfig_ProducerConfig() = default;
22008 TraceConfig_ProducerConfig::TraceConfig_ProducerConfig(const TraceConfig_ProducerConfig&) = default;
22009 TraceConfig_ProducerConfig& TraceConfig_ProducerConfig::operator=(const TraceConfig_ProducerConfig&) = default;
22010 TraceConfig_ProducerConfig::TraceConfig_ProducerConfig(TraceConfig_ProducerConfig&&) noexcept = default;
22011 TraceConfig_ProducerConfig& TraceConfig_ProducerConfig::operator=(TraceConfig_ProducerConfig&&) = default;
22012 
operator ==(const TraceConfig_ProducerConfig & other) const22013 bool TraceConfig_ProducerConfig::operator==(const TraceConfig_ProducerConfig& other) const {
22014   return unknown_fields_ == other.unknown_fields_
22015    && producer_name_ == other.producer_name_
22016    && shm_size_kb_ == other.shm_size_kb_
22017    && page_size_kb_ == other.page_size_kb_;
22018 }
22019 
ParseFromArray(const void * raw,size_t size)22020 bool TraceConfig_ProducerConfig::ParseFromArray(const void* raw, size_t size) {
22021   unknown_fields_.clear();
22022   bool packed_error = false;
22023 
22024   ::protozero::ProtoDecoder dec(raw, size);
22025   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
22026     if (field.id() < _has_field_.size()) {
22027       _has_field_.set(field.id());
22028     }
22029     switch (field.id()) {
22030       case 1 /* producer_name */:
22031         field.get(&producer_name_);
22032         break;
22033       case 2 /* shm_size_kb */:
22034         field.get(&shm_size_kb_);
22035         break;
22036       case 3 /* page_size_kb */:
22037         field.get(&page_size_kb_);
22038         break;
22039       default:
22040         field.SerializeAndAppendTo(&unknown_fields_);
22041         break;
22042     }
22043   }
22044   return !packed_error && !dec.bytes_left();
22045 }
22046 
SerializeAsString() const22047 std::string TraceConfig_ProducerConfig::SerializeAsString() const {
22048   ::protozero::HeapBuffered<::protozero::Message> msg;
22049   Serialize(msg.get());
22050   return msg.SerializeAsString();
22051 }
22052 
SerializeAsArray() const22053 std::vector<uint8_t> TraceConfig_ProducerConfig::SerializeAsArray() const {
22054   ::protozero::HeapBuffered<::protozero::Message> msg;
22055   Serialize(msg.get());
22056   return msg.SerializeAsArray();
22057 }
22058 
Serialize(::protozero::Message * msg) const22059 void TraceConfig_ProducerConfig::Serialize(::protozero::Message* msg) const {
22060   // Field 1: producer_name
22061   if (_has_field_[1]) {
22062     msg->AppendString(1, producer_name_);
22063   }
22064 
22065   // Field 2: shm_size_kb
22066   if (_has_field_[2]) {
22067     msg->AppendVarInt(2, shm_size_kb_);
22068   }
22069 
22070   // Field 3: page_size_kb
22071   if (_has_field_[3]) {
22072     msg->AppendVarInt(3, page_size_kb_);
22073   }
22074 
22075   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
22076 }
22077 
22078 
22079 TraceConfig_BuiltinDataSource::TraceConfig_BuiltinDataSource() = default;
22080 TraceConfig_BuiltinDataSource::~TraceConfig_BuiltinDataSource() = default;
22081 TraceConfig_BuiltinDataSource::TraceConfig_BuiltinDataSource(const TraceConfig_BuiltinDataSource&) = default;
22082 TraceConfig_BuiltinDataSource& TraceConfig_BuiltinDataSource::operator=(const TraceConfig_BuiltinDataSource&) = default;
22083 TraceConfig_BuiltinDataSource::TraceConfig_BuiltinDataSource(TraceConfig_BuiltinDataSource&&) noexcept = default;
22084 TraceConfig_BuiltinDataSource& TraceConfig_BuiltinDataSource::operator=(TraceConfig_BuiltinDataSource&&) = default;
22085 
operator ==(const TraceConfig_BuiltinDataSource & other) const22086 bool TraceConfig_BuiltinDataSource::operator==(const TraceConfig_BuiltinDataSource& other) const {
22087   return unknown_fields_ == other.unknown_fields_
22088    && disable_clock_snapshotting_ == other.disable_clock_snapshotting_
22089    && disable_trace_config_ == other.disable_trace_config_
22090    && disable_system_info_ == other.disable_system_info_
22091    && disable_service_events_ == other.disable_service_events_
22092    && primary_trace_clock_ == other.primary_trace_clock_
22093    && snapshot_interval_ms_ == other.snapshot_interval_ms_
22094    && prefer_suspend_clock_for_snapshot_ == other.prefer_suspend_clock_for_snapshot_;
22095 }
22096 
ParseFromArray(const void * raw,size_t size)22097 bool TraceConfig_BuiltinDataSource::ParseFromArray(const void* raw, size_t size) {
22098   unknown_fields_.clear();
22099   bool packed_error = false;
22100 
22101   ::protozero::ProtoDecoder dec(raw, size);
22102   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
22103     if (field.id() < _has_field_.size()) {
22104       _has_field_.set(field.id());
22105     }
22106     switch (field.id()) {
22107       case 1 /* disable_clock_snapshotting */:
22108         field.get(&disable_clock_snapshotting_);
22109         break;
22110       case 2 /* disable_trace_config */:
22111         field.get(&disable_trace_config_);
22112         break;
22113       case 3 /* disable_system_info */:
22114         field.get(&disable_system_info_);
22115         break;
22116       case 4 /* disable_service_events */:
22117         field.get(&disable_service_events_);
22118         break;
22119       case 5 /* primary_trace_clock */:
22120         field.get(&primary_trace_clock_);
22121         break;
22122       case 6 /* snapshot_interval_ms */:
22123         field.get(&snapshot_interval_ms_);
22124         break;
22125       case 7 /* prefer_suspend_clock_for_snapshot */:
22126         field.get(&prefer_suspend_clock_for_snapshot_);
22127         break;
22128       default:
22129         field.SerializeAndAppendTo(&unknown_fields_);
22130         break;
22131     }
22132   }
22133   return !packed_error && !dec.bytes_left();
22134 }
22135 
SerializeAsString() const22136 std::string TraceConfig_BuiltinDataSource::SerializeAsString() const {
22137   ::protozero::HeapBuffered<::protozero::Message> msg;
22138   Serialize(msg.get());
22139   return msg.SerializeAsString();
22140 }
22141 
SerializeAsArray() const22142 std::vector<uint8_t> TraceConfig_BuiltinDataSource::SerializeAsArray() const {
22143   ::protozero::HeapBuffered<::protozero::Message> msg;
22144   Serialize(msg.get());
22145   return msg.SerializeAsArray();
22146 }
22147 
Serialize(::protozero::Message * msg) const22148 void TraceConfig_BuiltinDataSource::Serialize(::protozero::Message* msg) const {
22149   // Field 1: disable_clock_snapshotting
22150   if (_has_field_[1]) {
22151     msg->AppendTinyVarInt(1, disable_clock_snapshotting_);
22152   }
22153 
22154   // Field 2: disable_trace_config
22155   if (_has_field_[2]) {
22156     msg->AppendTinyVarInt(2, disable_trace_config_);
22157   }
22158 
22159   // Field 3: disable_system_info
22160   if (_has_field_[3]) {
22161     msg->AppendTinyVarInt(3, disable_system_info_);
22162   }
22163 
22164   // Field 4: disable_service_events
22165   if (_has_field_[4]) {
22166     msg->AppendTinyVarInt(4, disable_service_events_);
22167   }
22168 
22169   // Field 5: primary_trace_clock
22170   if (_has_field_[5]) {
22171     msg->AppendVarInt(5, primary_trace_clock_);
22172   }
22173 
22174   // Field 6: snapshot_interval_ms
22175   if (_has_field_[6]) {
22176     msg->AppendVarInt(6, snapshot_interval_ms_);
22177   }
22178 
22179   // Field 7: prefer_suspend_clock_for_snapshot
22180   if (_has_field_[7]) {
22181     msg->AppendTinyVarInt(7, prefer_suspend_clock_for_snapshot_);
22182   }
22183 
22184   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
22185 }
22186 
22187 
22188 TraceConfig_DataSource::TraceConfig_DataSource() = default;
22189 TraceConfig_DataSource::~TraceConfig_DataSource() = default;
22190 TraceConfig_DataSource::TraceConfig_DataSource(const TraceConfig_DataSource&) = default;
22191 TraceConfig_DataSource& TraceConfig_DataSource::operator=(const TraceConfig_DataSource&) = default;
22192 TraceConfig_DataSource::TraceConfig_DataSource(TraceConfig_DataSource&&) noexcept = default;
22193 TraceConfig_DataSource& TraceConfig_DataSource::operator=(TraceConfig_DataSource&&) = default;
22194 
operator ==(const TraceConfig_DataSource & other) const22195 bool TraceConfig_DataSource::operator==(const TraceConfig_DataSource& other) const {
22196   return unknown_fields_ == other.unknown_fields_
22197    && config_ == other.config_
22198    && producer_name_filter_ == other.producer_name_filter_
22199    && producer_name_regex_filter_ == other.producer_name_regex_filter_;
22200 }
22201 
ParseFromArray(const void * raw,size_t size)22202 bool TraceConfig_DataSource::ParseFromArray(const void* raw, size_t size) {
22203   producer_name_filter_.clear();
22204   producer_name_regex_filter_.clear();
22205   unknown_fields_.clear();
22206   bool packed_error = false;
22207 
22208   ::protozero::ProtoDecoder dec(raw, size);
22209   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
22210     if (field.id() < _has_field_.size()) {
22211       _has_field_.set(field.id());
22212     }
22213     switch (field.id()) {
22214       case 1 /* config */:
22215         (*config_).ParseFromArray(field.data(), field.size());
22216         break;
22217       case 2 /* producer_name_filter */:
22218         producer_name_filter_.emplace_back();
22219         field.get(&producer_name_filter_.back());
22220         break;
22221       case 3 /* producer_name_regex_filter */:
22222         producer_name_regex_filter_.emplace_back();
22223         field.get(&producer_name_regex_filter_.back());
22224         break;
22225       default:
22226         field.SerializeAndAppendTo(&unknown_fields_);
22227         break;
22228     }
22229   }
22230   return !packed_error && !dec.bytes_left();
22231 }
22232 
SerializeAsString() const22233 std::string TraceConfig_DataSource::SerializeAsString() const {
22234   ::protozero::HeapBuffered<::protozero::Message> msg;
22235   Serialize(msg.get());
22236   return msg.SerializeAsString();
22237 }
22238 
SerializeAsArray() const22239 std::vector<uint8_t> TraceConfig_DataSource::SerializeAsArray() const {
22240   ::protozero::HeapBuffered<::protozero::Message> msg;
22241   Serialize(msg.get());
22242   return msg.SerializeAsArray();
22243 }
22244 
Serialize(::protozero::Message * msg) const22245 void TraceConfig_DataSource::Serialize(::protozero::Message* msg) const {
22246   // Field 1: config
22247   if (_has_field_[1]) {
22248     (*config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
22249   }
22250 
22251   // Field 2: producer_name_filter
22252   for (auto& it : producer_name_filter_) {
22253     msg->AppendString(2, it);
22254   }
22255 
22256   // Field 3: producer_name_regex_filter
22257   for (auto& it : producer_name_regex_filter_) {
22258     msg->AppendString(3, it);
22259   }
22260 
22261   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
22262 }
22263 
22264 
22265 TraceConfig_BufferConfig::TraceConfig_BufferConfig() = default;
22266 TraceConfig_BufferConfig::~TraceConfig_BufferConfig() = default;
22267 TraceConfig_BufferConfig::TraceConfig_BufferConfig(const TraceConfig_BufferConfig&) = default;
22268 TraceConfig_BufferConfig& TraceConfig_BufferConfig::operator=(const TraceConfig_BufferConfig&) = default;
22269 TraceConfig_BufferConfig::TraceConfig_BufferConfig(TraceConfig_BufferConfig&&) noexcept = default;
22270 TraceConfig_BufferConfig& TraceConfig_BufferConfig::operator=(TraceConfig_BufferConfig&&) = default;
22271 
operator ==(const TraceConfig_BufferConfig & other) const22272 bool TraceConfig_BufferConfig::operator==(const TraceConfig_BufferConfig& other) const {
22273   return unknown_fields_ == other.unknown_fields_
22274    && size_kb_ == other.size_kb_
22275    && fill_policy_ == other.fill_policy_;
22276 }
22277 
ParseFromArray(const void * raw,size_t size)22278 bool TraceConfig_BufferConfig::ParseFromArray(const void* raw, size_t size) {
22279   unknown_fields_.clear();
22280   bool packed_error = false;
22281 
22282   ::protozero::ProtoDecoder dec(raw, size);
22283   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
22284     if (field.id() < _has_field_.size()) {
22285       _has_field_.set(field.id());
22286     }
22287     switch (field.id()) {
22288       case 1 /* size_kb */:
22289         field.get(&size_kb_);
22290         break;
22291       case 4 /* fill_policy */:
22292         field.get(&fill_policy_);
22293         break;
22294       default:
22295         field.SerializeAndAppendTo(&unknown_fields_);
22296         break;
22297     }
22298   }
22299   return !packed_error && !dec.bytes_left();
22300 }
22301 
SerializeAsString() const22302 std::string TraceConfig_BufferConfig::SerializeAsString() const {
22303   ::protozero::HeapBuffered<::protozero::Message> msg;
22304   Serialize(msg.get());
22305   return msg.SerializeAsString();
22306 }
22307 
SerializeAsArray() const22308 std::vector<uint8_t> TraceConfig_BufferConfig::SerializeAsArray() const {
22309   ::protozero::HeapBuffered<::protozero::Message> msg;
22310   Serialize(msg.get());
22311   return msg.SerializeAsArray();
22312 }
22313 
Serialize(::protozero::Message * msg) const22314 void TraceConfig_BufferConfig::Serialize(::protozero::Message* msg) const {
22315   // Field 1: size_kb
22316   if (_has_field_[1]) {
22317     msg->AppendVarInt(1, size_kb_);
22318   }
22319 
22320   // Field 4: fill_policy
22321   if (_has_field_[4]) {
22322     msg->AppendVarInt(4, fill_policy_);
22323   }
22324 
22325   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
22326 }
22327 
22328 }  // namespace perfetto
22329 }  // namespace protos
22330 }  // namespace gen
22331 #if defined(__GNUC__) || defined(__clang__)
22332 #pragma GCC diagnostic pop
22333 #endif
22334 // gen_amalgamated begin source: gen/protos/perfetto/common/android_energy_consumer_descriptor.pbzero.cc
22335 // Intentionally empty (crbug.com/998165)
22336 // gen_amalgamated begin source: gen/protos/perfetto/common/android_log_constants.pbzero.cc
22337 // Intentionally empty (crbug.com/998165)
22338 // gen_amalgamated begin source: gen/protos/perfetto/common/builtin_clock.pbzero.cc
22339 // Intentionally empty (crbug.com/998165)
22340 // gen_amalgamated begin source: gen/protos/perfetto/common/commit_data_request.pbzero.cc
22341 // Intentionally empty (crbug.com/998165)
22342 // gen_amalgamated begin source: gen/protos/perfetto/common/data_source_descriptor.pbzero.cc
22343 // Intentionally empty (crbug.com/998165)
22344 // gen_amalgamated begin source: gen/protos/perfetto/common/descriptor.pbzero.cc
22345 // Intentionally empty (crbug.com/998165)
22346 // gen_amalgamated begin source: gen/protos/perfetto/common/gpu_counter_descriptor.pbzero.cc
22347 // Intentionally empty (crbug.com/998165)
22348 // gen_amalgamated begin source: gen/protos/perfetto/common/interceptor_descriptor.pbzero.cc
22349 // Intentionally empty (crbug.com/998165)
22350 // gen_amalgamated begin source: gen/protos/perfetto/common/observable_events.pbzero.cc
22351 // Intentionally empty (crbug.com/998165)
22352 // gen_amalgamated begin source: gen/protos/perfetto/common/perf_events.pbzero.cc
22353 // Intentionally empty (crbug.com/998165)
22354 // gen_amalgamated begin source: gen/protos/perfetto/common/sys_stats_counters.pbzero.cc
22355 // Intentionally empty (crbug.com/998165)
22356 // gen_amalgamated begin source: gen/protos/perfetto/common/trace_stats.pbzero.cc
22357 // Intentionally empty (crbug.com/998165)
22358 // gen_amalgamated begin source: gen/protos/perfetto/common/tracing_service_capabilities.pbzero.cc
22359 // Intentionally empty (crbug.com/998165)
22360 // gen_amalgamated begin source: gen/protos/perfetto/common/tracing_service_state.pbzero.cc
22361 // Intentionally empty (crbug.com/998165)
22362 // gen_amalgamated begin source: gen/protos/perfetto/common/track_event_descriptor.pbzero.cc
22363 // Intentionally empty (crbug.com/998165)
22364 // gen_amalgamated begin source: gen/protos/perfetto/trace/gpu/gpu_counter_event.pbzero.cc
22365 // Intentionally empty (crbug.com/998165)
22366 // gen_amalgamated begin source: gen/protos/perfetto/trace/gpu/gpu_log.pbzero.cc
22367 // Intentionally empty (crbug.com/998165)
22368 // gen_amalgamated begin source: gen/protos/perfetto/trace/gpu/gpu_render_stage_event.pbzero.cc
22369 // Intentionally empty (crbug.com/998165)
22370 // gen_amalgamated begin source: gen/protos/perfetto/trace/gpu/vulkan_api_event.pbzero.cc
22371 // Intentionally empty (crbug.com/998165)
22372 // gen_amalgamated begin source: gen/protos/perfetto/trace/gpu/vulkan_memory_event.pbzero.cc
22373 // Intentionally empty (crbug.com/998165)
22374 // gen_amalgamated begin source: gen/protos/perfetto/trace/profiling/deobfuscation.pbzero.cc
22375 // Intentionally empty (crbug.com/998165)
22376 // gen_amalgamated begin source: gen/protos/perfetto/trace/profiling/heap_graph.pbzero.cc
22377 // Intentionally empty (crbug.com/998165)
22378 // gen_amalgamated begin source: gen/protos/perfetto/trace/profiling/profile_common.pbzero.cc
22379 // Intentionally empty (crbug.com/998165)
22380 // gen_amalgamated begin source: gen/protos/perfetto/trace/profiling/profile_packet.pbzero.cc
22381 // Intentionally empty (crbug.com/998165)
22382 // gen_amalgamated begin source: gen/protos/perfetto/trace/profiling/smaps.pbzero.cc
22383 // Intentionally empty (crbug.com/998165)
22384 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_application_state_info.pbzero.cc
22385 // Intentionally empty (crbug.com/998165)
22386 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.pbzero.cc
22387 // Intentionally empty (crbug.com/998165)
22388 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_content_settings_event_info.pbzero.cc
22389 // Intentionally empty (crbug.com/998165)
22390 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_frame_reporter.pbzero.cc
22391 // Intentionally empty (crbug.com/998165)
22392 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_histogram_sample.pbzero.cc
22393 // Intentionally empty (crbug.com/998165)
22394 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_keyed_service.pbzero.cc
22395 // Intentionally empty (crbug.com/998165)
22396 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_latency_info.pbzero.cc
22397 // Intentionally empty (crbug.com/998165)
22398 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_legacy_ipc.pbzero.cc
22399 // Intentionally empty (crbug.com/998165)
22400 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_message_pump.pbzero.cc
22401 // Intentionally empty (crbug.com/998165)
22402 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_mojo_event_info.pbzero.cc
22403 // Intentionally empty (crbug.com/998165)
22404 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_process_descriptor.pbzero.cc
22405 // Intentionally empty (crbug.com/998165)
22406 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.pbzero.cc
22407 // Intentionally empty (crbug.com/998165)
22408 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_thread_descriptor.pbzero.cc
22409 // Intentionally empty (crbug.com/998165)
22410 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_user_event.pbzero.cc
22411 // Intentionally empty (crbug.com/998165)
22412 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_window_handle_event_info.pbzero.cc
22413 // Intentionally empty (crbug.com/998165)
22414 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/counter_descriptor.pbzero.cc
22415 // Intentionally empty (crbug.com/998165)
22416 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/debug_annotation.pbzero.cc
22417 // Intentionally empty (crbug.com/998165)
22418 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/log_message.pbzero.cc
22419 // Intentionally empty (crbug.com/998165)
22420 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/process_descriptor.pbzero.cc
22421 // Intentionally empty (crbug.com/998165)
22422 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/source_location.pbzero.cc
22423 // Intentionally empty (crbug.com/998165)
22424 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/task_execution.pbzero.cc
22425 // Intentionally empty (crbug.com/998165)
22426 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/thread_descriptor.pbzero.cc
22427 // Intentionally empty (crbug.com/998165)
22428 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/track_descriptor.pbzero.cc
22429 // Intentionally empty (crbug.com/998165)
22430 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/track_event.pbzero.cc
22431 // Intentionally empty (crbug.com/998165)
22432 // gen_amalgamated begin source: gen/protos/perfetto/trace/interned_data/interned_data.pbzero.cc
22433 // Intentionally empty (crbug.com/998165)
22434 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_application_state_info.gen.cc
22435 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_application_state_info.gen.h
22436 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
22437 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_APPLICATION_STATE_INFO_PROTO_CPP_H_
22438 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_APPLICATION_STATE_INFO_PROTO_CPP_H_
22439 
22440 #include <stdint.h>
22441 #include <bitset>
22442 #include <vector>
22443 #include <string>
22444 #include <type_traits>
22445 
22446 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
22447 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
22448 // gen_amalgamated expanded: #include "perfetto/base/export.h"
22449 
22450 namespace perfetto {
22451 namespace protos {
22452 namespace gen {
22453 class ChromeApplicationStateInfo;
22454 enum ChromeApplicationStateInfo_ChromeApplicationState : int;
22455 }  // namespace perfetto
22456 }  // namespace protos
22457 }  // namespace gen
22458 
22459 namespace protozero {
22460 class Message;
22461 }  // namespace protozero
22462 
22463 namespace perfetto {
22464 namespace protos {
22465 namespace gen {
22466 enum ChromeApplicationStateInfo_ChromeApplicationState : int {
22467   ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_UNKNOWN = 0,
22468   ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_RUNNING_ACTIVITIES = 1,
22469   ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_PAUSED_ACTIVITIES = 2,
22470   ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_STOPPED_ACTIVITIES = 3,
22471   ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES = 4,
22472 };
22473 
22474 class PERFETTO_EXPORT ChromeApplicationStateInfo : public ::protozero::CppMessageObj {
22475  public:
22476   using ChromeApplicationState = ChromeApplicationStateInfo_ChromeApplicationState;
22477   static constexpr auto APPLICATION_STATE_UNKNOWN = ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_UNKNOWN;
22478   static constexpr auto APPLICATION_STATE_HAS_RUNNING_ACTIVITIES = ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_RUNNING_ACTIVITIES;
22479   static constexpr auto APPLICATION_STATE_HAS_PAUSED_ACTIVITIES = ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_PAUSED_ACTIVITIES;
22480   static constexpr auto APPLICATION_STATE_HAS_STOPPED_ACTIVITIES = ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_STOPPED_ACTIVITIES;
22481   static constexpr auto APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES = ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES;
22482   static constexpr auto ChromeApplicationState_MIN = ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_UNKNOWN;
22483   static constexpr auto ChromeApplicationState_MAX = ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES;
22484   enum FieldNumbers {
22485     kApplicationStateFieldNumber = 1,
22486   };
22487 
22488   ChromeApplicationStateInfo();
22489   ~ChromeApplicationStateInfo() override;
22490   ChromeApplicationStateInfo(ChromeApplicationStateInfo&&) noexcept;
22491   ChromeApplicationStateInfo& operator=(ChromeApplicationStateInfo&&);
22492   ChromeApplicationStateInfo(const ChromeApplicationStateInfo&);
22493   ChromeApplicationStateInfo& operator=(const ChromeApplicationStateInfo&);
22494   bool operator==(const ChromeApplicationStateInfo&) const;
operator !=(const ChromeApplicationStateInfo & other) const22495   bool operator!=(const ChromeApplicationStateInfo& other) const { return !(*this == other); }
22496 
22497   bool ParseFromArray(const void*, size_t) override;
22498   std::string SerializeAsString() const override;
22499   std::vector<uint8_t> SerializeAsArray() const override;
22500   void Serialize(::protozero::Message*) const;
22501 
has_application_state() const22502   bool has_application_state() const { return _has_field_[1]; }
application_state() const22503   ChromeApplicationStateInfo_ChromeApplicationState application_state() const { return application_state_; }
set_application_state(ChromeApplicationStateInfo_ChromeApplicationState value)22504   void set_application_state(ChromeApplicationStateInfo_ChromeApplicationState value) { application_state_ = value; _has_field_.set(1); }
22505 
22506  private:
22507   ChromeApplicationStateInfo_ChromeApplicationState application_state_{};
22508 
22509   // Allows to preserve unknown protobuf fields for compatibility
22510   // with future versions of .proto files.
22511   std::string unknown_fields_;
22512 
22513   std::bitset<2> _has_field_{};
22514 };
22515 
22516 }  // namespace perfetto
22517 }  // namespace protos
22518 }  // namespace gen
22519 
22520 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_APPLICATION_STATE_INFO_PROTO_CPP_H_
22521 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
22522 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
22523 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
22524 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
22525 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
22526 #if defined(__GNUC__) || defined(__clang__)
22527 #pragma GCC diagnostic push
22528 #pragma GCC diagnostic ignored "-Wfloat-equal"
22529 #endif
22530 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_application_state_info.gen.h"
22531 
22532 namespace perfetto {
22533 namespace protos {
22534 namespace gen {
22535 
22536 ChromeApplicationStateInfo::ChromeApplicationStateInfo() = default;
22537 ChromeApplicationStateInfo::~ChromeApplicationStateInfo() = default;
22538 ChromeApplicationStateInfo::ChromeApplicationStateInfo(const ChromeApplicationStateInfo&) = default;
22539 ChromeApplicationStateInfo& ChromeApplicationStateInfo::operator=(const ChromeApplicationStateInfo&) = default;
22540 ChromeApplicationStateInfo::ChromeApplicationStateInfo(ChromeApplicationStateInfo&&) noexcept = default;
22541 ChromeApplicationStateInfo& ChromeApplicationStateInfo::operator=(ChromeApplicationStateInfo&&) = default;
22542 
operator ==(const ChromeApplicationStateInfo & other) const22543 bool ChromeApplicationStateInfo::operator==(const ChromeApplicationStateInfo& other) const {
22544   return unknown_fields_ == other.unknown_fields_
22545    && application_state_ == other.application_state_;
22546 }
22547 
ParseFromArray(const void * raw,size_t size)22548 bool ChromeApplicationStateInfo::ParseFromArray(const void* raw, size_t size) {
22549   unknown_fields_.clear();
22550   bool packed_error = false;
22551 
22552   ::protozero::ProtoDecoder dec(raw, size);
22553   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
22554     if (field.id() < _has_field_.size()) {
22555       _has_field_.set(field.id());
22556     }
22557     switch (field.id()) {
22558       case 1 /* application_state */:
22559         field.get(&application_state_);
22560         break;
22561       default:
22562         field.SerializeAndAppendTo(&unknown_fields_);
22563         break;
22564     }
22565   }
22566   return !packed_error && !dec.bytes_left();
22567 }
22568 
SerializeAsString() const22569 std::string ChromeApplicationStateInfo::SerializeAsString() const {
22570   ::protozero::HeapBuffered<::protozero::Message> msg;
22571   Serialize(msg.get());
22572   return msg.SerializeAsString();
22573 }
22574 
SerializeAsArray() const22575 std::vector<uint8_t> ChromeApplicationStateInfo::SerializeAsArray() const {
22576   ::protozero::HeapBuffered<::protozero::Message> msg;
22577   Serialize(msg.get());
22578   return msg.SerializeAsArray();
22579 }
22580 
Serialize(::protozero::Message * msg) const22581 void ChromeApplicationStateInfo::Serialize(::protozero::Message* msg) const {
22582   // Field 1: application_state
22583   if (_has_field_[1]) {
22584     msg->AppendVarInt(1, application_state_);
22585   }
22586 
22587   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
22588 }
22589 
22590 }  // namespace perfetto
22591 }  // namespace protos
22592 }  // namespace gen
22593 #if defined(__GNUC__) || defined(__clang__)
22594 #pragma GCC diagnostic pop
22595 #endif
22596 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.gen.cc
22597 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.gen.h
22598 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
22599 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_COMPOSITOR_SCHEDULER_STATE_PROTO_CPP_H_
22600 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_COMPOSITOR_SCHEDULER_STATE_PROTO_CPP_H_
22601 
22602 #include <stdint.h>
22603 #include <bitset>
22604 #include <vector>
22605 #include <string>
22606 #include <type_traits>
22607 
22608 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
22609 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
22610 // gen_amalgamated expanded: #include "perfetto/base/export.h"
22611 
22612 namespace perfetto {
22613 namespace protos {
22614 namespace gen {
22615 class CompositorTimingHistory;
22616 class BeginFrameSourceState;
22617 class BeginFrameArgs;
22618 class SourceLocation;
22619 class BeginFrameObserverState;
22620 class BeginImplFrameArgs;
22621 class BeginImplFrameArgs_TimestampsInUs;
22622 class ChromeCompositorStateMachine;
22623 class ChromeCompositorStateMachine_MinorState;
22624 class ChromeCompositorStateMachine_MajorState;
22625 class ChromeCompositorSchedulerState;
22626 enum ChromeCompositorSchedulerAction : int;
22627 enum BeginFrameArgs_BeginFrameArgsType : int;
22628 enum BeginImplFrameArgs_State : int;
22629 enum ChromeCompositorStateMachine_MinorState_TreePriority : int;
22630 enum ChromeCompositorStateMachine_MinorState_ScrollHandlerState : int;
22631 enum ChromeCompositorStateMachine_MajorState_BeginImplFrameState : int;
22632 enum ChromeCompositorStateMachine_MajorState_BeginMainFrameState : int;
22633 enum ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState : int;
22634 enum ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState : int;
22635 enum ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode : int;
22636 }  // namespace perfetto
22637 }  // namespace protos
22638 }  // namespace gen
22639 
22640 namespace protozero {
22641 class Message;
22642 }  // namespace protozero
22643 
22644 namespace perfetto {
22645 namespace protos {
22646 namespace gen {
22647 enum ChromeCompositorSchedulerAction : int {
22648   CC_SCHEDULER_ACTION_UNSPECIFIED = 0,
22649   CC_SCHEDULER_ACTION_NONE = 1,
22650   CC_SCHEDULER_ACTION_SEND_BEGIN_MAIN_FRAME = 2,
22651   CC_SCHEDULER_ACTION_COMMIT = 3,
22652   CC_SCHEDULER_ACTION_ACTIVATE_SYNC_TREE = 4,
22653   CC_SCHEDULER_ACTION_DRAW_IF_POSSIBLE = 5,
22654   CC_SCHEDULER_ACTION_DRAW_FORCED = 6,
22655   CC_SCHEDULER_ACTION_DRAW_ABORT = 7,
22656   CC_SCHEDULER_ACTION_BEGIN_LAYER_TREE_FRAME_SINK_CREATION = 8,
22657   CC_SCHEDULER_ACTION_PREPARE_TILES = 9,
22658   CC_SCHEDULER_ACTION_INVALIDATE_LAYER_TREE_FRAME_SINK = 10,
22659   CC_SCHEDULER_ACTION_PERFORM_IMPL_SIDE_INVALIDATION = 11,
22660   CC_SCHEDULER_ACTION_NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_UNTIL = 12,
22661   CC_SCHEDULER_ACTION_NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_SOON = 13,
22662 };
22663 enum BeginFrameArgs_BeginFrameArgsType : int {
22664   BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED = 0,
22665   BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_INVALID = 1,
22666   BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_NORMAL = 2,
22667   BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_MISSED = 3,
22668 };
22669 enum BeginImplFrameArgs_State : int {
22670   BeginImplFrameArgs_State_BEGIN_FRAME_FINISHED = 0,
22671   BeginImplFrameArgs_State_BEGIN_FRAME_USING = 1,
22672 };
22673 enum ChromeCompositorStateMachine_MinorState_TreePriority : int {
22674   ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_UNSPECIFIED = 0,
22675   ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_SAME_PRIORITY_FOR_BOTH_TREES = 1,
22676   ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_SMOOTHNESS_TAKES_PRIORITY = 2,
22677   ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY = 3,
22678 };
22679 enum ChromeCompositorStateMachine_MinorState_ScrollHandlerState : int {
22680   ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_HANDLER_UNSPECIFIED = 0,
22681   ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_AFFECTS_SCROLL_HANDLER = 1,
22682   ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER = 2,
22683 };
22684 enum ChromeCompositorStateMachine_MajorState_BeginImplFrameState : int {
22685   ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_UNSPECIFIED = 0,
22686   ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_IDLE = 1,
22687   ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_INSIDE_BEGIN_FRAME = 2,
22688   ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_INSIDE_DEADLINE = 3,
22689 };
22690 enum ChromeCompositorStateMachine_MajorState_BeginMainFrameState : int {
22691   ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_UNSPECIFIED = 0,
22692   ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_IDLE = 1,
22693   ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_SENT = 2,
22694   ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_READY_TO_COMMIT = 3,
22695 };
22696 enum ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState : int {
22697   ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_UNSPECIFIED = 0,
22698   ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_NONE = 1,
22699   ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_ACTIVE = 2,
22700   ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_CREATING = 3,
22701   ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_WAITING_FOR_FIRST_COMMIT = 4,
22702   ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION = 5,
22703 };
22704 enum ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState : int {
22705   ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_UNSPECIFIED = 0,
22706   ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_IDLE = 1,
22707   ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_COMMIT = 2,
22708   ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_ACTIVATION = 3,
22709   ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_DRAW = 4,
22710 };
22711 enum ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode : int {
22712   ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_UNSPECIFIED = 0,
22713   ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_NONE = 1,
22714   ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_IMMEDIATE = 2,
22715   ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_REGULAR = 3,
22716   ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_LATE = 4,
22717   ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_BLOCKED = 5,
22718 };
22719 
22720 class PERFETTO_EXPORT CompositorTimingHistory : public ::protozero::CppMessageObj {
22721  public:
22722   enum FieldNumbers {
22723     kBeginMainFrameQueueCriticalEstimateDeltaUsFieldNumber = 1,
22724     kBeginMainFrameQueueNotCriticalEstimateDeltaUsFieldNumber = 2,
22725     kBeginMainFrameStartToReadyToCommitEstimateDeltaUsFieldNumber = 3,
22726     kCommitToReadyToActivateEstimateDeltaUsFieldNumber = 4,
22727     kPrepareTilesEstimateDeltaUsFieldNumber = 5,
22728     kActivateEstimateDeltaUsFieldNumber = 6,
22729     kDrawEstimateDeltaUsFieldNumber = 7,
22730   };
22731 
22732   CompositorTimingHistory();
22733   ~CompositorTimingHistory() override;
22734   CompositorTimingHistory(CompositorTimingHistory&&) noexcept;
22735   CompositorTimingHistory& operator=(CompositorTimingHistory&&);
22736   CompositorTimingHistory(const CompositorTimingHistory&);
22737   CompositorTimingHistory& operator=(const CompositorTimingHistory&);
22738   bool operator==(const CompositorTimingHistory&) const;
operator !=(const CompositorTimingHistory & other) const22739   bool operator!=(const CompositorTimingHistory& other) const { return !(*this == other); }
22740 
22741   bool ParseFromArray(const void*, size_t) override;
22742   std::string SerializeAsString() const override;
22743   std::vector<uint8_t> SerializeAsArray() const override;
22744   void Serialize(::protozero::Message*) const;
22745 
has_begin_main_frame_queue_critical_estimate_delta_us() const22746   bool has_begin_main_frame_queue_critical_estimate_delta_us() const { return _has_field_[1]; }
begin_main_frame_queue_critical_estimate_delta_us() const22747   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)22748   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); }
22749 
has_begin_main_frame_queue_not_critical_estimate_delta_us() const22750   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() const22751   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)22752   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); }
22753 
has_begin_main_frame_start_to_ready_to_commit_estimate_delta_us() const22754   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() const22755   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)22756   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); }
22757 
has_commit_to_ready_to_activate_estimate_delta_us() const22758   bool has_commit_to_ready_to_activate_estimate_delta_us() const { return _has_field_[4]; }
commit_to_ready_to_activate_estimate_delta_us() const22759   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)22760   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); }
22761 
has_prepare_tiles_estimate_delta_us() const22762   bool has_prepare_tiles_estimate_delta_us() const { return _has_field_[5]; }
prepare_tiles_estimate_delta_us() const22763   int64_t prepare_tiles_estimate_delta_us() const { return prepare_tiles_estimate_delta_us_; }
set_prepare_tiles_estimate_delta_us(int64_t value)22764   void set_prepare_tiles_estimate_delta_us(int64_t value) { prepare_tiles_estimate_delta_us_ = value; _has_field_.set(5); }
22765 
has_activate_estimate_delta_us() const22766   bool has_activate_estimate_delta_us() const { return _has_field_[6]; }
activate_estimate_delta_us() const22767   int64_t activate_estimate_delta_us() const { return activate_estimate_delta_us_; }
set_activate_estimate_delta_us(int64_t value)22768   void set_activate_estimate_delta_us(int64_t value) { activate_estimate_delta_us_ = value; _has_field_.set(6); }
22769 
has_draw_estimate_delta_us() const22770   bool has_draw_estimate_delta_us() const { return _has_field_[7]; }
draw_estimate_delta_us() const22771   int64_t draw_estimate_delta_us() const { return draw_estimate_delta_us_; }
set_draw_estimate_delta_us(int64_t value)22772   void set_draw_estimate_delta_us(int64_t value) { draw_estimate_delta_us_ = value; _has_field_.set(7); }
22773 
22774  private:
22775   int64_t begin_main_frame_queue_critical_estimate_delta_us_{};
22776   int64_t begin_main_frame_queue_not_critical_estimate_delta_us_{};
22777   int64_t begin_main_frame_start_to_ready_to_commit_estimate_delta_us_{};
22778   int64_t commit_to_ready_to_activate_estimate_delta_us_{};
22779   int64_t prepare_tiles_estimate_delta_us_{};
22780   int64_t activate_estimate_delta_us_{};
22781   int64_t draw_estimate_delta_us_{};
22782 
22783   // Allows to preserve unknown protobuf fields for compatibility
22784   // with future versions of .proto files.
22785   std::string unknown_fields_;
22786 
22787   std::bitset<8> _has_field_{};
22788 };
22789 
22790 
22791 class PERFETTO_EXPORT BeginFrameSourceState : public ::protozero::CppMessageObj {
22792  public:
22793   enum FieldNumbers {
22794     kSourceIdFieldNumber = 1,
22795     kPausedFieldNumber = 2,
22796     kNumObserversFieldNumber = 3,
22797     kLastBeginFrameArgsFieldNumber = 4,
22798   };
22799 
22800   BeginFrameSourceState();
22801   ~BeginFrameSourceState() override;
22802   BeginFrameSourceState(BeginFrameSourceState&&) noexcept;
22803   BeginFrameSourceState& operator=(BeginFrameSourceState&&);
22804   BeginFrameSourceState(const BeginFrameSourceState&);
22805   BeginFrameSourceState& operator=(const BeginFrameSourceState&);
22806   bool operator==(const BeginFrameSourceState&) const;
operator !=(const BeginFrameSourceState & other) const22807   bool operator!=(const BeginFrameSourceState& other) const { return !(*this == other); }
22808 
22809   bool ParseFromArray(const void*, size_t) override;
22810   std::string SerializeAsString() const override;
22811   std::vector<uint8_t> SerializeAsArray() const override;
22812   void Serialize(::protozero::Message*) const;
22813 
has_source_id() const22814   bool has_source_id() const { return _has_field_[1]; }
source_id() const22815   uint32_t source_id() const { return source_id_; }
set_source_id(uint32_t value)22816   void set_source_id(uint32_t value) { source_id_ = value; _has_field_.set(1); }
22817 
has_paused() const22818   bool has_paused() const { return _has_field_[2]; }
paused() const22819   bool paused() const { return paused_; }
set_paused(bool value)22820   void set_paused(bool value) { paused_ = value; _has_field_.set(2); }
22821 
has_num_observers() const22822   bool has_num_observers() const { return _has_field_[3]; }
num_observers() const22823   uint32_t num_observers() const { return num_observers_; }
set_num_observers(uint32_t value)22824   void set_num_observers(uint32_t value) { num_observers_ = value; _has_field_.set(3); }
22825 
has_last_begin_frame_args() const22826   bool has_last_begin_frame_args() const { return _has_field_[4]; }
last_begin_frame_args() const22827   const BeginFrameArgs& last_begin_frame_args() const { return *last_begin_frame_args_; }
mutable_last_begin_frame_args()22828   BeginFrameArgs* mutable_last_begin_frame_args() { _has_field_.set(4); return last_begin_frame_args_.get(); }
22829 
22830  private:
22831   uint32_t source_id_{};
22832   bool paused_{};
22833   uint32_t num_observers_{};
22834   ::protozero::CopyablePtr<BeginFrameArgs> last_begin_frame_args_;
22835 
22836   // Allows to preserve unknown protobuf fields for compatibility
22837   // with future versions of .proto files.
22838   std::string unknown_fields_;
22839 
22840   std::bitset<5> _has_field_{};
22841 };
22842 
22843 
22844 class PERFETTO_EXPORT BeginFrameArgs : public ::protozero::CppMessageObj {
22845  public:
22846   using BeginFrameArgsType = BeginFrameArgs_BeginFrameArgsType;
22847   static constexpr auto BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED;
22848   static constexpr auto BEGIN_FRAME_ARGS_TYPE_INVALID = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_INVALID;
22849   static constexpr auto BEGIN_FRAME_ARGS_TYPE_NORMAL = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_NORMAL;
22850   static constexpr auto BEGIN_FRAME_ARGS_TYPE_MISSED = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_MISSED;
22851   static constexpr auto BeginFrameArgsType_MIN = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED;
22852   static constexpr auto BeginFrameArgsType_MAX = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_MISSED;
22853   enum FieldNumbers {
22854     kTypeFieldNumber = 1,
22855     kSourceIdFieldNumber = 2,
22856     kSequenceNumberFieldNumber = 3,
22857     kFrameTimeUsFieldNumber = 4,
22858     kDeadlineUsFieldNumber = 5,
22859     kIntervalDeltaUsFieldNumber = 6,
22860     kOnCriticalPathFieldNumber = 7,
22861     kAnimateOnlyFieldNumber = 8,
22862     kSourceLocationIidFieldNumber = 9,
22863     kSourceLocationFieldNumber = 10,
22864   };
22865 
22866   BeginFrameArgs();
22867   ~BeginFrameArgs() override;
22868   BeginFrameArgs(BeginFrameArgs&&) noexcept;
22869   BeginFrameArgs& operator=(BeginFrameArgs&&);
22870   BeginFrameArgs(const BeginFrameArgs&);
22871   BeginFrameArgs& operator=(const BeginFrameArgs&);
22872   bool operator==(const BeginFrameArgs&) const;
operator !=(const BeginFrameArgs & other) const22873   bool operator!=(const BeginFrameArgs& other) const { return !(*this == other); }
22874 
22875   bool ParseFromArray(const void*, size_t) override;
22876   std::string SerializeAsString() const override;
22877   std::vector<uint8_t> SerializeAsArray() const override;
22878   void Serialize(::protozero::Message*) const;
22879 
has_type() const22880   bool has_type() const { return _has_field_[1]; }
type() const22881   BeginFrameArgs_BeginFrameArgsType type() const { return type_; }
set_type(BeginFrameArgs_BeginFrameArgsType value)22882   void set_type(BeginFrameArgs_BeginFrameArgsType value) { type_ = value; _has_field_.set(1); }
22883 
has_source_id() const22884   bool has_source_id() const { return _has_field_[2]; }
source_id() const22885   uint64_t source_id() const { return source_id_; }
set_source_id(uint64_t value)22886   void set_source_id(uint64_t value) { source_id_ = value; _has_field_.set(2); }
22887 
has_sequence_number() const22888   bool has_sequence_number() const { return _has_field_[3]; }
sequence_number() const22889   uint64_t sequence_number() const { return sequence_number_; }
set_sequence_number(uint64_t value)22890   void set_sequence_number(uint64_t value) { sequence_number_ = value; _has_field_.set(3); }
22891 
has_frame_time_us() const22892   bool has_frame_time_us() const { return _has_field_[4]; }
frame_time_us() const22893   int64_t frame_time_us() const { return frame_time_us_; }
set_frame_time_us(int64_t value)22894   void set_frame_time_us(int64_t value) { frame_time_us_ = value; _has_field_.set(4); }
22895 
has_deadline_us() const22896   bool has_deadline_us() const { return _has_field_[5]; }
deadline_us() const22897   int64_t deadline_us() const { return deadline_us_; }
set_deadline_us(int64_t value)22898   void set_deadline_us(int64_t value) { deadline_us_ = value; _has_field_.set(5); }
22899 
has_interval_delta_us() const22900   bool has_interval_delta_us() const { return _has_field_[6]; }
interval_delta_us() const22901   int64_t interval_delta_us() const { return interval_delta_us_; }
set_interval_delta_us(int64_t value)22902   void set_interval_delta_us(int64_t value) { interval_delta_us_ = value; _has_field_.set(6); }
22903 
has_on_critical_path() const22904   bool has_on_critical_path() const { return _has_field_[7]; }
on_critical_path() const22905   bool on_critical_path() const { return on_critical_path_; }
set_on_critical_path(bool value)22906   void set_on_critical_path(bool value) { on_critical_path_ = value; _has_field_.set(7); }
22907 
has_animate_only() const22908   bool has_animate_only() const { return _has_field_[8]; }
animate_only() const22909   bool animate_only() const { return animate_only_; }
set_animate_only(bool value)22910   void set_animate_only(bool value) { animate_only_ = value; _has_field_.set(8); }
22911 
has_source_location_iid() const22912   bool has_source_location_iid() const { return _has_field_[9]; }
source_location_iid() const22913   uint64_t source_location_iid() const { return source_location_iid_; }
set_source_location_iid(uint64_t value)22914   void set_source_location_iid(uint64_t value) { source_location_iid_ = value; _has_field_.set(9); }
22915 
has_source_location() const22916   bool has_source_location() const { return _has_field_[10]; }
source_location() const22917   const SourceLocation& source_location() const { return *source_location_; }
mutable_source_location()22918   SourceLocation* mutable_source_location() { _has_field_.set(10); return source_location_.get(); }
22919 
22920  private:
22921   BeginFrameArgs_BeginFrameArgsType type_{};
22922   uint64_t source_id_{};
22923   uint64_t sequence_number_{};
22924   int64_t frame_time_us_{};
22925   int64_t deadline_us_{};
22926   int64_t interval_delta_us_{};
22927   bool on_critical_path_{};
22928   bool animate_only_{};
22929   uint64_t source_location_iid_{};
22930   ::protozero::CopyablePtr<SourceLocation> source_location_;
22931 
22932   // Allows to preserve unknown protobuf fields for compatibility
22933   // with future versions of .proto files.
22934   std::string unknown_fields_;
22935 
22936   std::bitset<11> _has_field_{};
22937 };
22938 
22939 
22940 class PERFETTO_EXPORT BeginFrameObserverState : public ::protozero::CppMessageObj {
22941  public:
22942   enum FieldNumbers {
22943     kDroppedBeginFrameArgsFieldNumber = 1,
22944     kLastBeginFrameArgsFieldNumber = 2,
22945   };
22946 
22947   BeginFrameObserverState();
22948   ~BeginFrameObserverState() override;
22949   BeginFrameObserverState(BeginFrameObserverState&&) noexcept;
22950   BeginFrameObserverState& operator=(BeginFrameObserverState&&);
22951   BeginFrameObserverState(const BeginFrameObserverState&);
22952   BeginFrameObserverState& operator=(const BeginFrameObserverState&);
22953   bool operator==(const BeginFrameObserverState&) const;
operator !=(const BeginFrameObserverState & other) const22954   bool operator!=(const BeginFrameObserverState& other) const { return !(*this == other); }
22955 
22956   bool ParseFromArray(const void*, size_t) override;
22957   std::string SerializeAsString() const override;
22958   std::vector<uint8_t> SerializeAsArray() const override;
22959   void Serialize(::protozero::Message*) const;
22960 
has_dropped_begin_frame_args() const22961   bool has_dropped_begin_frame_args() const { return _has_field_[1]; }
dropped_begin_frame_args() const22962   int64_t dropped_begin_frame_args() const { return dropped_begin_frame_args_; }
set_dropped_begin_frame_args(int64_t value)22963   void set_dropped_begin_frame_args(int64_t value) { dropped_begin_frame_args_ = value; _has_field_.set(1); }
22964 
has_last_begin_frame_args() const22965   bool has_last_begin_frame_args() const { return _has_field_[2]; }
last_begin_frame_args() const22966   const BeginFrameArgs& last_begin_frame_args() const { return *last_begin_frame_args_; }
mutable_last_begin_frame_args()22967   BeginFrameArgs* mutable_last_begin_frame_args() { _has_field_.set(2); return last_begin_frame_args_.get(); }
22968 
22969  private:
22970   int64_t dropped_begin_frame_args_{};
22971   ::protozero::CopyablePtr<BeginFrameArgs> last_begin_frame_args_;
22972 
22973   // Allows to preserve unknown protobuf fields for compatibility
22974   // with future versions of .proto files.
22975   std::string unknown_fields_;
22976 
22977   std::bitset<3> _has_field_{};
22978 };
22979 
22980 
22981 class PERFETTO_EXPORT BeginImplFrameArgs : public ::protozero::CppMessageObj {
22982  public:
22983   using TimestampsInUs = BeginImplFrameArgs_TimestampsInUs;
22984   using State = BeginImplFrameArgs_State;
22985   static constexpr auto BEGIN_FRAME_FINISHED = BeginImplFrameArgs_State_BEGIN_FRAME_FINISHED;
22986   static constexpr auto BEGIN_FRAME_USING = BeginImplFrameArgs_State_BEGIN_FRAME_USING;
22987   static constexpr auto State_MIN = BeginImplFrameArgs_State_BEGIN_FRAME_FINISHED;
22988   static constexpr auto State_MAX = BeginImplFrameArgs_State_BEGIN_FRAME_USING;
22989   enum FieldNumbers {
22990     kUpdatedAtUsFieldNumber = 1,
22991     kFinishedAtUsFieldNumber = 2,
22992     kStateFieldNumber = 3,
22993     kCurrentArgsFieldNumber = 4,
22994     kLastArgsFieldNumber = 5,
22995     kTimestampsInUsFieldNumber = 6,
22996   };
22997 
22998   BeginImplFrameArgs();
22999   ~BeginImplFrameArgs() override;
23000   BeginImplFrameArgs(BeginImplFrameArgs&&) noexcept;
23001   BeginImplFrameArgs& operator=(BeginImplFrameArgs&&);
23002   BeginImplFrameArgs(const BeginImplFrameArgs&);
23003   BeginImplFrameArgs& operator=(const BeginImplFrameArgs&);
23004   bool operator==(const BeginImplFrameArgs&) const;
operator !=(const BeginImplFrameArgs & other) const23005   bool operator!=(const BeginImplFrameArgs& other) const { return !(*this == other); }
23006 
23007   bool ParseFromArray(const void*, size_t) override;
23008   std::string SerializeAsString() const override;
23009   std::vector<uint8_t> SerializeAsArray() const override;
23010   void Serialize(::protozero::Message*) const;
23011 
has_updated_at_us() const23012   bool has_updated_at_us() const { return _has_field_[1]; }
updated_at_us() const23013   int64_t updated_at_us() const { return updated_at_us_; }
set_updated_at_us(int64_t value)23014   void set_updated_at_us(int64_t value) { updated_at_us_ = value; _has_field_.set(1); }
23015 
has_finished_at_us() const23016   bool has_finished_at_us() const { return _has_field_[2]; }
finished_at_us() const23017   int64_t finished_at_us() const { return finished_at_us_; }
set_finished_at_us(int64_t value)23018   void set_finished_at_us(int64_t value) { finished_at_us_ = value; _has_field_.set(2); }
23019 
has_state() const23020   bool has_state() const { return _has_field_[3]; }
state() const23021   BeginImplFrameArgs_State state() const { return state_; }
set_state(BeginImplFrameArgs_State value)23022   void set_state(BeginImplFrameArgs_State value) { state_ = value; _has_field_.set(3); }
23023 
has_current_args() const23024   bool has_current_args() const { return _has_field_[4]; }
current_args() const23025   const BeginFrameArgs& current_args() const { return *current_args_; }
mutable_current_args()23026   BeginFrameArgs* mutable_current_args() { _has_field_.set(4); return current_args_.get(); }
23027 
has_last_args() const23028   bool has_last_args() const { return _has_field_[5]; }
last_args() const23029   const BeginFrameArgs& last_args() const { return *last_args_; }
mutable_last_args()23030   BeginFrameArgs* mutable_last_args() { _has_field_.set(5); return last_args_.get(); }
23031 
has_timestamps_in_us() const23032   bool has_timestamps_in_us() const { return _has_field_[6]; }
timestamps_in_us() const23033   const BeginImplFrameArgs_TimestampsInUs& timestamps_in_us() const { return *timestamps_in_us_; }
mutable_timestamps_in_us()23034   BeginImplFrameArgs_TimestampsInUs* mutable_timestamps_in_us() { _has_field_.set(6); return timestamps_in_us_.get(); }
23035 
23036  private:
23037   int64_t updated_at_us_{};
23038   int64_t finished_at_us_{};
23039   BeginImplFrameArgs_State state_{};
23040   ::protozero::CopyablePtr<BeginFrameArgs> current_args_;
23041   ::protozero::CopyablePtr<BeginFrameArgs> last_args_;
23042   ::protozero::CopyablePtr<BeginImplFrameArgs_TimestampsInUs> timestamps_in_us_;
23043 
23044   // Allows to preserve unknown protobuf fields for compatibility
23045   // with future versions of .proto files.
23046   std::string unknown_fields_;
23047 
23048   std::bitset<7> _has_field_{};
23049 };
23050 
23051 
23052 class PERFETTO_EXPORT BeginImplFrameArgs_TimestampsInUs : public ::protozero::CppMessageObj {
23053  public:
23054   enum FieldNumbers {
23055     kIntervalDeltaFieldNumber = 1,
23056     kNowToDeadlineDeltaFieldNumber = 2,
23057     kFrameTimeToNowDeltaFieldNumber = 3,
23058     kFrameTimeToDeadlineDeltaFieldNumber = 4,
23059     kNowFieldNumber = 5,
23060     kFrameTimeFieldNumber = 6,
23061     kDeadlineFieldNumber = 7,
23062   };
23063 
23064   BeginImplFrameArgs_TimestampsInUs();
23065   ~BeginImplFrameArgs_TimestampsInUs() override;
23066   BeginImplFrameArgs_TimestampsInUs(BeginImplFrameArgs_TimestampsInUs&&) noexcept;
23067   BeginImplFrameArgs_TimestampsInUs& operator=(BeginImplFrameArgs_TimestampsInUs&&);
23068   BeginImplFrameArgs_TimestampsInUs(const BeginImplFrameArgs_TimestampsInUs&);
23069   BeginImplFrameArgs_TimestampsInUs& operator=(const BeginImplFrameArgs_TimestampsInUs&);
23070   bool operator==(const BeginImplFrameArgs_TimestampsInUs&) const;
operator !=(const BeginImplFrameArgs_TimestampsInUs & other) const23071   bool operator!=(const BeginImplFrameArgs_TimestampsInUs& other) const { return !(*this == other); }
23072 
23073   bool ParseFromArray(const void*, size_t) override;
23074   std::string SerializeAsString() const override;
23075   std::vector<uint8_t> SerializeAsArray() const override;
23076   void Serialize(::protozero::Message*) const;
23077 
has_interval_delta() const23078   bool has_interval_delta() const { return _has_field_[1]; }
interval_delta() const23079   int64_t interval_delta() const { return interval_delta_; }
set_interval_delta(int64_t value)23080   void set_interval_delta(int64_t value) { interval_delta_ = value; _has_field_.set(1); }
23081 
has_now_to_deadline_delta() const23082   bool has_now_to_deadline_delta() const { return _has_field_[2]; }
now_to_deadline_delta() const23083   int64_t now_to_deadline_delta() const { return now_to_deadline_delta_; }
set_now_to_deadline_delta(int64_t value)23084   void set_now_to_deadline_delta(int64_t value) { now_to_deadline_delta_ = value; _has_field_.set(2); }
23085 
has_frame_time_to_now_delta() const23086   bool has_frame_time_to_now_delta() const { return _has_field_[3]; }
frame_time_to_now_delta() const23087   int64_t frame_time_to_now_delta() const { return frame_time_to_now_delta_; }
set_frame_time_to_now_delta(int64_t value)23088   void set_frame_time_to_now_delta(int64_t value) { frame_time_to_now_delta_ = value; _has_field_.set(3); }
23089 
has_frame_time_to_deadline_delta() const23090   bool has_frame_time_to_deadline_delta() const { return _has_field_[4]; }
frame_time_to_deadline_delta() const23091   int64_t frame_time_to_deadline_delta() const { return frame_time_to_deadline_delta_; }
set_frame_time_to_deadline_delta(int64_t value)23092   void set_frame_time_to_deadline_delta(int64_t value) { frame_time_to_deadline_delta_ = value; _has_field_.set(4); }
23093 
has_now() const23094   bool has_now() const { return _has_field_[5]; }
now() const23095   int64_t now() const { return now_; }
set_now(int64_t value)23096   void set_now(int64_t value) { now_ = value; _has_field_.set(5); }
23097 
has_frame_time() const23098   bool has_frame_time() const { return _has_field_[6]; }
frame_time() const23099   int64_t frame_time() const { return frame_time_; }
set_frame_time(int64_t value)23100   void set_frame_time(int64_t value) { frame_time_ = value; _has_field_.set(6); }
23101 
has_deadline() const23102   bool has_deadline() const { return _has_field_[7]; }
deadline() const23103   int64_t deadline() const { return deadline_; }
set_deadline(int64_t value)23104   void set_deadline(int64_t value) { deadline_ = value; _has_field_.set(7); }
23105 
23106  private:
23107   int64_t interval_delta_{};
23108   int64_t now_to_deadline_delta_{};
23109   int64_t frame_time_to_now_delta_{};
23110   int64_t frame_time_to_deadline_delta_{};
23111   int64_t now_{};
23112   int64_t frame_time_{};
23113   int64_t deadline_{};
23114 
23115   // Allows to preserve unknown protobuf fields for compatibility
23116   // with future versions of .proto files.
23117   std::string unknown_fields_;
23118 
23119   std::bitset<8> _has_field_{};
23120 };
23121 
23122 
23123 class PERFETTO_EXPORT ChromeCompositorStateMachine : public ::protozero::CppMessageObj {
23124  public:
23125   using MajorState = ChromeCompositorStateMachine_MajorState;
23126   using MinorState = ChromeCompositorStateMachine_MinorState;
23127   enum FieldNumbers {
23128     kMajorStateFieldNumber = 1,
23129     kMinorStateFieldNumber = 2,
23130   };
23131 
23132   ChromeCompositorStateMachine();
23133   ~ChromeCompositorStateMachine() override;
23134   ChromeCompositorStateMachine(ChromeCompositorStateMachine&&) noexcept;
23135   ChromeCompositorStateMachine& operator=(ChromeCompositorStateMachine&&);
23136   ChromeCompositorStateMachine(const ChromeCompositorStateMachine&);
23137   ChromeCompositorStateMachine& operator=(const ChromeCompositorStateMachine&);
23138   bool operator==(const ChromeCompositorStateMachine&) const;
operator !=(const ChromeCompositorStateMachine & other) const23139   bool operator!=(const ChromeCompositorStateMachine& other) const { return !(*this == other); }
23140 
23141   bool ParseFromArray(const void*, size_t) override;
23142   std::string SerializeAsString() const override;
23143   std::vector<uint8_t> SerializeAsArray() const override;
23144   void Serialize(::protozero::Message*) const;
23145 
has_major_state() const23146   bool has_major_state() const { return _has_field_[1]; }
major_state() const23147   const ChromeCompositorStateMachine_MajorState& major_state() const { return *major_state_; }
mutable_major_state()23148   ChromeCompositorStateMachine_MajorState* mutable_major_state() { _has_field_.set(1); return major_state_.get(); }
23149 
has_minor_state() const23150   bool has_minor_state() const { return _has_field_[2]; }
minor_state() const23151   const ChromeCompositorStateMachine_MinorState& minor_state() const { return *minor_state_; }
mutable_minor_state()23152   ChromeCompositorStateMachine_MinorState* mutable_minor_state() { _has_field_.set(2); return minor_state_.get(); }
23153 
23154  private:
23155   ::protozero::CopyablePtr<ChromeCompositorStateMachine_MajorState> major_state_;
23156   ::protozero::CopyablePtr<ChromeCompositorStateMachine_MinorState> minor_state_;
23157 
23158   // Allows to preserve unknown protobuf fields for compatibility
23159   // with future versions of .proto files.
23160   std::string unknown_fields_;
23161 
23162   std::bitset<3> _has_field_{};
23163 };
23164 
23165 
23166 class PERFETTO_EXPORT ChromeCompositorStateMachine_MinorState : public ::protozero::CppMessageObj {
23167  public:
23168   using TreePriority = ChromeCompositorStateMachine_MinorState_TreePriority;
23169   static constexpr auto TREE_PRIORITY_UNSPECIFIED = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_UNSPECIFIED;
23170   static constexpr auto TREE_PRIORITY_SAME_PRIORITY_FOR_BOTH_TREES = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_SAME_PRIORITY_FOR_BOTH_TREES;
23171   static constexpr auto TREE_PRIORITY_SMOOTHNESS_TAKES_PRIORITY = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_SMOOTHNESS_TAKES_PRIORITY;
23172   static constexpr auto TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY;
23173   static constexpr auto TreePriority_MIN = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_UNSPECIFIED;
23174   static constexpr auto TreePriority_MAX = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY;
23175   using ScrollHandlerState = ChromeCompositorStateMachine_MinorState_ScrollHandlerState;
23176   static constexpr auto SCROLL_HANDLER_UNSPECIFIED = ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_HANDLER_UNSPECIFIED;
23177   static constexpr auto SCROLL_AFFECTS_SCROLL_HANDLER = ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_AFFECTS_SCROLL_HANDLER;
23178   static constexpr auto SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER = ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER;
23179   static constexpr auto ScrollHandlerState_MIN = ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_HANDLER_UNSPECIFIED;
23180   static constexpr auto ScrollHandlerState_MAX = ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER;
23181   enum FieldNumbers {
23182     kCommitCountFieldNumber = 1,
23183     kCurrentFrameNumberFieldNumber = 2,
23184     kLastFrameNumberSubmitPerformedFieldNumber = 3,
23185     kLastFrameNumberDrawPerformedFieldNumber = 4,
23186     kLastFrameNumberBeginMainFrameSentFieldNumber = 5,
23187     kDidDrawFieldNumber = 6,
23188     kDidSendBeginMainFrameForCurrentFrameFieldNumber = 7,
23189     kDidNotifyBeginMainFrameNotExpectedUntilFieldNumber = 8,
23190     kDidNotifyBeginMainFrameNotExpectedSoonFieldNumber = 9,
23191     kWantsBeginMainFrameNotExpectedFieldNumber = 10,
23192     kDidCommitDuringFrameFieldNumber = 11,
23193     kDidInvalidateLayerTreeFrameSinkFieldNumber = 12,
23194     kDidPerformImplSideInvalidaionFieldNumber = 13,
23195     kDidPrepareTilesFieldNumber = 14,
23196     kConsecutiveCheckerboardAnimationsFieldNumber = 15,
23197     kPendingSubmitFramesFieldNumber = 16,
23198     kSubmitFramesWithCurrentLayerTreeFrameSinkFieldNumber = 17,
23199     kNeedsRedrawFieldNumber = 18,
23200     kNeedsPrepareTilesFieldNumber = 19,
23201     kNeedsBeginMainFrameFieldNumber = 20,
23202     kNeedsOneBeginImplFrameFieldNumber = 21,
23203     kVisibleFieldNumber = 22,
23204     kBeginFrameSourcePausedFieldNumber = 23,
23205     kCanDrawFieldNumber = 24,
23206     kResourcelessDrawFieldNumber = 25,
23207     kHasPendingTreeFieldNumber = 26,
23208     kPendingTreeIsReadyForActivationFieldNumber = 27,
23209     kActiveTreeNeedsFirstDrawFieldNumber = 28,
23210     kActiveTreeIsReadyToDrawFieldNumber = 29,
23211     kDidCreateAndInitializeFirstLayerTreeFrameSinkFieldNumber = 30,
23212     kTreePriorityFieldNumber = 31,
23213     kScrollHandlerStateFieldNumber = 32,
23214     kCriticalBeginMainFrameToActivateIsFastFieldNumber = 33,
23215     kMainThreadMissedLastDeadlineFieldNumber = 34,
23216     kSkipNextBeginMainFrameToReduceLatencyFieldNumber = 35,
23217     kVideoNeedsBeginFramesFieldNumber = 36,
23218     kDeferBeginMainFrameFieldNumber = 37,
23219     kLastCommitHadNoUpdatesFieldNumber = 38,
23220     kDidDrawInLastFrameFieldNumber = 39,
23221     kDidSubmitInLastFrameFieldNumber = 40,
23222     kNeedsImplSideInvalidationFieldNumber = 41,
23223     kCurrentPendingTreeIsImplSideFieldNumber = 42,
23224     kPreviousPendingTreeWasImplSideFieldNumber = 43,
23225     kProcessingAnimationWorkletsForActiveTreeFieldNumber = 44,
23226     kProcessingAnimationWorkletsForPendingTreeFieldNumber = 45,
23227     kProcessingPaintWorkletsForPendingTreeFieldNumber = 46,
23228   };
23229 
23230   ChromeCompositorStateMachine_MinorState();
23231   ~ChromeCompositorStateMachine_MinorState() override;
23232   ChromeCompositorStateMachine_MinorState(ChromeCompositorStateMachine_MinorState&&) noexcept;
23233   ChromeCompositorStateMachine_MinorState& operator=(ChromeCompositorStateMachine_MinorState&&);
23234   ChromeCompositorStateMachine_MinorState(const ChromeCompositorStateMachine_MinorState&);
23235   ChromeCompositorStateMachine_MinorState& operator=(const ChromeCompositorStateMachine_MinorState&);
23236   bool operator==(const ChromeCompositorStateMachine_MinorState&) const;
operator !=(const ChromeCompositorStateMachine_MinorState & other) const23237   bool operator!=(const ChromeCompositorStateMachine_MinorState& other) const { return !(*this == other); }
23238 
23239   bool ParseFromArray(const void*, size_t) override;
23240   std::string SerializeAsString() const override;
23241   std::vector<uint8_t> SerializeAsArray() const override;
23242   void Serialize(::protozero::Message*) const;
23243 
has_commit_count() const23244   bool has_commit_count() const { return _has_field_[1]; }
commit_count() const23245   int32_t commit_count() const { return commit_count_; }
set_commit_count(int32_t value)23246   void set_commit_count(int32_t value) { commit_count_ = value; _has_field_.set(1); }
23247 
has_current_frame_number() const23248   bool has_current_frame_number() const { return _has_field_[2]; }
current_frame_number() const23249   int32_t current_frame_number() const { return current_frame_number_; }
set_current_frame_number(int32_t value)23250   void set_current_frame_number(int32_t value) { current_frame_number_ = value; _has_field_.set(2); }
23251 
has_last_frame_number_submit_performed() const23252   bool has_last_frame_number_submit_performed() const { return _has_field_[3]; }
last_frame_number_submit_performed() const23253   int32_t last_frame_number_submit_performed() const { return last_frame_number_submit_performed_; }
set_last_frame_number_submit_performed(int32_t value)23254   void set_last_frame_number_submit_performed(int32_t value) { last_frame_number_submit_performed_ = value; _has_field_.set(3); }
23255 
has_last_frame_number_draw_performed() const23256   bool has_last_frame_number_draw_performed() const { return _has_field_[4]; }
last_frame_number_draw_performed() const23257   int32_t last_frame_number_draw_performed() const { return last_frame_number_draw_performed_; }
set_last_frame_number_draw_performed(int32_t value)23258   void set_last_frame_number_draw_performed(int32_t value) { last_frame_number_draw_performed_ = value; _has_field_.set(4); }
23259 
has_last_frame_number_begin_main_frame_sent() const23260   bool has_last_frame_number_begin_main_frame_sent() const { return _has_field_[5]; }
last_frame_number_begin_main_frame_sent() const23261   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)23262   void set_last_frame_number_begin_main_frame_sent(int32_t value) { last_frame_number_begin_main_frame_sent_ = value; _has_field_.set(5); }
23263 
has_did_draw() const23264   bool has_did_draw() const { return _has_field_[6]; }
did_draw() const23265   bool did_draw() const { return did_draw_; }
set_did_draw(bool value)23266   void set_did_draw(bool value) { did_draw_ = value; _has_field_.set(6); }
23267 
has_did_send_begin_main_frame_for_current_frame() const23268   bool has_did_send_begin_main_frame_for_current_frame() const { return _has_field_[7]; }
did_send_begin_main_frame_for_current_frame() const23269   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)23270   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); }
23271 
has_did_notify_begin_main_frame_not_expected_until() const23272   bool has_did_notify_begin_main_frame_not_expected_until() const { return _has_field_[8]; }
did_notify_begin_main_frame_not_expected_until() const23273   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)23274   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); }
23275 
has_did_notify_begin_main_frame_not_expected_soon() const23276   bool has_did_notify_begin_main_frame_not_expected_soon() const { return _has_field_[9]; }
did_notify_begin_main_frame_not_expected_soon() const23277   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)23278   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); }
23279 
has_wants_begin_main_frame_not_expected() const23280   bool has_wants_begin_main_frame_not_expected() const { return _has_field_[10]; }
wants_begin_main_frame_not_expected() const23281   bool wants_begin_main_frame_not_expected() const { return wants_begin_main_frame_not_expected_; }
set_wants_begin_main_frame_not_expected(bool value)23282   void set_wants_begin_main_frame_not_expected(bool value) { wants_begin_main_frame_not_expected_ = value; _has_field_.set(10); }
23283 
has_did_commit_during_frame() const23284   bool has_did_commit_during_frame() const { return _has_field_[11]; }
did_commit_during_frame() const23285   bool did_commit_during_frame() const { return did_commit_during_frame_; }
set_did_commit_during_frame(bool value)23286   void set_did_commit_during_frame(bool value) { did_commit_during_frame_ = value; _has_field_.set(11); }
23287 
has_did_invalidate_layer_tree_frame_sink() const23288   bool has_did_invalidate_layer_tree_frame_sink() const { return _has_field_[12]; }
did_invalidate_layer_tree_frame_sink() const23289   bool did_invalidate_layer_tree_frame_sink() const { return did_invalidate_layer_tree_frame_sink_; }
set_did_invalidate_layer_tree_frame_sink(bool value)23290   void set_did_invalidate_layer_tree_frame_sink(bool value) { did_invalidate_layer_tree_frame_sink_ = value; _has_field_.set(12); }
23291 
has_did_perform_impl_side_invalidaion() const23292   bool has_did_perform_impl_side_invalidaion() const { return _has_field_[13]; }
did_perform_impl_side_invalidaion() const23293   bool did_perform_impl_side_invalidaion() const { return did_perform_impl_side_invalidaion_; }
set_did_perform_impl_side_invalidaion(bool value)23294   void set_did_perform_impl_side_invalidaion(bool value) { did_perform_impl_side_invalidaion_ = value; _has_field_.set(13); }
23295 
has_did_prepare_tiles() const23296   bool has_did_prepare_tiles() const { return _has_field_[14]; }
did_prepare_tiles() const23297   bool did_prepare_tiles() const { return did_prepare_tiles_; }
set_did_prepare_tiles(bool value)23298   void set_did_prepare_tiles(bool value) { did_prepare_tiles_ = value; _has_field_.set(14); }
23299 
has_consecutive_checkerboard_animations() const23300   bool has_consecutive_checkerboard_animations() const { return _has_field_[15]; }
consecutive_checkerboard_animations() const23301   int32_t consecutive_checkerboard_animations() const { return consecutive_checkerboard_animations_; }
set_consecutive_checkerboard_animations(int32_t value)23302   void set_consecutive_checkerboard_animations(int32_t value) { consecutive_checkerboard_animations_ = value; _has_field_.set(15); }
23303 
has_pending_submit_frames() const23304   bool has_pending_submit_frames() const { return _has_field_[16]; }
pending_submit_frames() const23305   int32_t pending_submit_frames() const { return pending_submit_frames_; }
set_pending_submit_frames(int32_t value)23306   void set_pending_submit_frames(int32_t value) { pending_submit_frames_ = value; _has_field_.set(16); }
23307 
has_submit_frames_with_current_layer_tree_frame_sink() const23308   bool has_submit_frames_with_current_layer_tree_frame_sink() const { return _has_field_[17]; }
submit_frames_with_current_layer_tree_frame_sink() const23309   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)23310   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); }
23311 
has_needs_redraw() const23312   bool has_needs_redraw() const { return _has_field_[18]; }
needs_redraw() const23313   bool needs_redraw() const { return needs_redraw_; }
set_needs_redraw(bool value)23314   void set_needs_redraw(bool value) { needs_redraw_ = value; _has_field_.set(18); }
23315 
has_needs_prepare_tiles() const23316   bool has_needs_prepare_tiles() const { return _has_field_[19]; }
needs_prepare_tiles() const23317   bool needs_prepare_tiles() const { return needs_prepare_tiles_; }
set_needs_prepare_tiles(bool value)23318   void set_needs_prepare_tiles(bool value) { needs_prepare_tiles_ = value; _has_field_.set(19); }
23319 
has_needs_begin_main_frame() const23320   bool has_needs_begin_main_frame() const { return _has_field_[20]; }
needs_begin_main_frame() const23321   bool needs_begin_main_frame() const { return needs_begin_main_frame_; }
set_needs_begin_main_frame(bool value)23322   void set_needs_begin_main_frame(bool value) { needs_begin_main_frame_ = value; _has_field_.set(20); }
23323 
has_needs_one_begin_impl_frame() const23324   bool has_needs_one_begin_impl_frame() const { return _has_field_[21]; }
needs_one_begin_impl_frame() const23325   bool needs_one_begin_impl_frame() const { return needs_one_begin_impl_frame_; }
set_needs_one_begin_impl_frame(bool value)23326   void set_needs_one_begin_impl_frame(bool value) { needs_one_begin_impl_frame_ = value; _has_field_.set(21); }
23327 
has_visible() const23328   bool has_visible() const { return _has_field_[22]; }
visible() const23329   bool visible() const { return visible_; }
set_visible(bool value)23330   void set_visible(bool value) { visible_ = value; _has_field_.set(22); }
23331 
has_begin_frame_source_paused() const23332   bool has_begin_frame_source_paused() const { return _has_field_[23]; }
begin_frame_source_paused() const23333   bool begin_frame_source_paused() const { return begin_frame_source_paused_; }
set_begin_frame_source_paused(bool value)23334   void set_begin_frame_source_paused(bool value) { begin_frame_source_paused_ = value; _has_field_.set(23); }
23335 
has_can_draw() const23336   bool has_can_draw() const { return _has_field_[24]; }
can_draw() const23337   bool can_draw() const { return can_draw_; }
set_can_draw(bool value)23338   void set_can_draw(bool value) { can_draw_ = value; _has_field_.set(24); }
23339 
has_resourceless_draw() const23340   bool has_resourceless_draw() const { return _has_field_[25]; }
resourceless_draw() const23341   bool resourceless_draw() const { return resourceless_draw_; }
set_resourceless_draw(bool value)23342   void set_resourceless_draw(bool value) { resourceless_draw_ = value; _has_field_.set(25); }
23343 
has_has_pending_tree() const23344   bool has_has_pending_tree() const { return _has_field_[26]; }
has_pending_tree() const23345   bool has_pending_tree() const { return has_pending_tree_; }
set_has_pending_tree(bool value)23346   void set_has_pending_tree(bool value) { has_pending_tree_ = value; _has_field_.set(26); }
23347 
has_pending_tree_is_ready_for_activation() const23348   bool has_pending_tree_is_ready_for_activation() const { return _has_field_[27]; }
pending_tree_is_ready_for_activation() const23349   bool pending_tree_is_ready_for_activation() const { return pending_tree_is_ready_for_activation_; }
set_pending_tree_is_ready_for_activation(bool value)23350   void set_pending_tree_is_ready_for_activation(bool value) { pending_tree_is_ready_for_activation_ = value; _has_field_.set(27); }
23351 
has_active_tree_needs_first_draw() const23352   bool has_active_tree_needs_first_draw() const { return _has_field_[28]; }
active_tree_needs_first_draw() const23353   bool active_tree_needs_first_draw() const { return active_tree_needs_first_draw_; }
set_active_tree_needs_first_draw(bool value)23354   void set_active_tree_needs_first_draw(bool value) { active_tree_needs_first_draw_ = value; _has_field_.set(28); }
23355 
has_active_tree_is_ready_to_draw() const23356   bool has_active_tree_is_ready_to_draw() const { return _has_field_[29]; }
active_tree_is_ready_to_draw() const23357   bool active_tree_is_ready_to_draw() const { return active_tree_is_ready_to_draw_; }
set_active_tree_is_ready_to_draw(bool value)23358   void set_active_tree_is_ready_to_draw(bool value) { active_tree_is_ready_to_draw_ = value; _has_field_.set(29); }
23359 
has_did_create_and_initialize_first_layer_tree_frame_sink() const23360   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() const23361   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)23362   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); }
23363 
has_tree_priority() const23364   bool has_tree_priority() const { return _has_field_[31]; }
tree_priority() const23365   ChromeCompositorStateMachine_MinorState_TreePriority tree_priority() const { return tree_priority_; }
set_tree_priority(ChromeCompositorStateMachine_MinorState_TreePriority value)23366   void set_tree_priority(ChromeCompositorStateMachine_MinorState_TreePriority value) { tree_priority_ = value; _has_field_.set(31); }
23367 
has_scroll_handler_state() const23368   bool has_scroll_handler_state() const { return _has_field_[32]; }
scroll_handler_state() const23369   ChromeCompositorStateMachine_MinorState_ScrollHandlerState scroll_handler_state() const { return scroll_handler_state_; }
set_scroll_handler_state(ChromeCompositorStateMachine_MinorState_ScrollHandlerState value)23370   void set_scroll_handler_state(ChromeCompositorStateMachine_MinorState_ScrollHandlerState value) { scroll_handler_state_ = value; _has_field_.set(32); }
23371 
has_critical_begin_main_frame_to_activate_is_fast() const23372   bool has_critical_begin_main_frame_to_activate_is_fast() const { return _has_field_[33]; }
critical_begin_main_frame_to_activate_is_fast() const23373   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)23374   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); }
23375 
has_main_thread_missed_last_deadline() const23376   bool has_main_thread_missed_last_deadline() const { return _has_field_[34]; }
main_thread_missed_last_deadline() const23377   bool main_thread_missed_last_deadline() const { return main_thread_missed_last_deadline_; }
set_main_thread_missed_last_deadline(bool value)23378   void set_main_thread_missed_last_deadline(bool value) { main_thread_missed_last_deadline_ = value; _has_field_.set(34); }
23379 
has_skip_next_begin_main_frame_to_reduce_latency() const23380   bool has_skip_next_begin_main_frame_to_reduce_latency() const { return _has_field_[35]; }
skip_next_begin_main_frame_to_reduce_latency() const23381   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)23382   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); }
23383 
has_video_needs_begin_frames() const23384   bool has_video_needs_begin_frames() const { return _has_field_[36]; }
video_needs_begin_frames() const23385   bool video_needs_begin_frames() const { return video_needs_begin_frames_; }
set_video_needs_begin_frames(bool value)23386   void set_video_needs_begin_frames(bool value) { video_needs_begin_frames_ = value; _has_field_.set(36); }
23387 
has_defer_begin_main_frame() const23388   bool has_defer_begin_main_frame() const { return _has_field_[37]; }
defer_begin_main_frame() const23389   bool defer_begin_main_frame() const { return defer_begin_main_frame_; }
set_defer_begin_main_frame(bool value)23390   void set_defer_begin_main_frame(bool value) { defer_begin_main_frame_ = value; _has_field_.set(37); }
23391 
has_last_commit_had_no_updates() const23392   bool has_last_commit_had_no_updates() const { return _has_field_[38]; }
last_commit_had_no_updates() const23393   bool last_commit_had_no_updates() const { return last_commit_had_no_updates_; }
set_last_commit_had_no_updates(bool value)23394   void set_last_commit_had_no_updates(bool value) { last_commit_had_no_updates_ = value; _has_field_.set(38); }
23395 
has_did_draw_in_last_frame() const23396   bool has_did_draw_in_last_frame() const { return _has_field_[39]; }
did_draw_in_last_frame() const23397   bool did_draw_in_last_frame() const { return did_draw_in_last_frame_; }
set_did_draw_in_last_frame(bool value)23398   void set_did_draw_in_last_frame(bool value) { did_draw_in_last_frame_ = value; _has_field_.set(39); }
23399 
has_did_submit_in_last_frame() const23400   bool has_did_submit_in_last_frame() const { return _has_field_[40]; }
did_submit_in_last_frame() const23401   bool did_submit_in_last_frame() const { return did_submit_in_last_frame_; }
set_did_submit_in_last_frame(bool value)23402   void set_did_submit_in_last_frame(bool value) { did_submit_in_last_frame_ = value; _has_field_.set(40); }
23403 
has_needs_impl_side_invalidation() const23404   bool has_needs_impl_side_invalidation() const { return _has_field_[41]; }
needs_impl_side_invalidation() const23405   bool needs_impl_side_invalidation() const { return needs_impl_side_invalidation_; }
set_needs_impl_side_invalidation(bool value)23406   void set_needs_impl_side_invalidation(bool value) { needs_impl_side_invalidation_ = value; _has_field_.set(41); }
23407 
has_current_pending_tree_is_impl_side() const23408   bool has_current_pending_tree_is_impl_side() const { return _has_field_[42]; }
current_pending_tree_is_impl_side() const23409   bool current_pending_tree_is_impl_side() const { return current_pending_tree_is_impl_side_; }
set_current_pending_tree_is_impl_side(bool value)23410   void set_current_pending_tree_is_impl_side(bool value) { current_pending_tree_is_impl_side_ = value; _has_field_.set(42); }
23411 
has_previous_pending_tree_was_impl_side() const23412   bool has_previous_pending_tree_was_impl_side() const { return _has_field_[43]; }
previous_pending_tree_was_impl_side() const23413   bool previous_pending_tree_was_impl_side() const { return previous_pending_tree_was_impl_side_; }
set_previous_pending_tree_was_impl_side(bool value)23414   void set_previous_pending_tree_was_impl_side(bool value) { previous_pending_tree_was_impl_side_ = value; _has_field_.set(43); }
23415 
has_processing_animation_worklets_for_active_tree() const23416   bool has_processing_animation_worklets_for_active_tree() const { return _has_field_[44]; }
processing_animation_worklets_for_active_tree() const23417   bool processing_animation_worklets_for_active_tree() const { return processing_animation_worklets_for_active_tree_; }
set_processing_animation_worklets_for_active_tree(bool value)23418   void set_processing_animation_worklets_for_active_tree(bool value) { processing_animation_worklets_for_active_tree_ = value; _has_field_.set(44); }
23419 
has_processing_animation_worklets_for_pending_tree() const23420   bool has_processing_animation_worklets_for_pending_tree() const { return _has_field_[45]; }
processing_animation_worklets_for_pending_tree() const23421   bool processing_animation_worklets_for_pending_tree() const { return processing_animation_worklets_for_pending_tree_; }
set_processing_animation_worklets_for_pending_tree(bool value)23422   void set_processing_animation_worklets_for_pending_tree(bool value) { processing_animation_worklets_for_pending_tree_ = value; _has_field_.set(45); }
23423 
has_processing_paint_worklets_for_pending_tree() const23424   bool has_processing_paint_worklets_for_pending_tree() const { return _has_field_[46]; }
processing_paint_worklets_for_pending_tree() const23425   bool processing_paint_worklets_for_pending_tree() const { return processing_paint_worklets_for_pending_tree_; }
set_processing_paint_worklets_for_pending_tree(bool value)23426   void set_processing_paint_worklets_for_pending_tree(bool value) { processing_paint_worklets_for_pending_tree_ = value; _has_field_.set(46); }
23427 
23428  private:
23429   int32_t commit_count_{};
23430   int32_t current_frame_number_{};
23431   int32_t last_frame_number_submit_performed_{};
23432   int32_t last_frame_number_draw_performed_{};
23433   int32_t last_frame_number_begin_main_frame_sent_{};
23434   bool did_draw_{};
23435   bool did_send_begin_main_frame_for_current_frame_{};
23436   bool did_notify_begin_main_frame_not_expected_until_{};
23437   bool did_notify_begin_main_frame_not_expected_soon_{};
23438   bool wants_begin_main_frame_not_expected_{};
23439   bool did_commit_during_frame_{};
23440   bool did_invalidate_layer_tree_frame_sink_{};
23441   bool did_perform_impl_side_invalidaion_{};
23442   bool did_prepare_tiles_{};
23443   int32_t consecutive_checkerboard_animations_{};
23444   int32_t pending_submit_frames_{};
23445   int32_t submit_frames_with_current_layer_tree_frame_sink_{};
23446   bool needs_redraw_{};
23447   bool needs_prepare_tiles_{};
23448   bool needs_begin_main_frame_{};
23449   bool needs_one_begin_impl_frame_{};
23450   bool visible_{};
23451   bool begin_frame_source_paused_{};
23452   bool can_draw_{};
23453   bool resourceless_draw_{};
23454   bool has_pending_tree_{};
23455   bool pending_tree_is_ready_for_activation_{};
23456   bool active_tree_needs_first_draw_{};
23457   bool active_tree_is_ready_to_draw_{};
23458   bool did_create_and_initialize_first_layer_tree_frame_sink_{};
23459   ChromeCompositorStateMachine_MinorState_TreePriority tree_priority_{};
23460   ChromeCompositorStateMachine_MinorState_ScrollHandlerState scroll_handler_state_{};
23461   bool critical_begin_main_frame_to_activate_is_fast_{};
23462   bool main_thread_missed_last_deadline_{};
23463   bool skip_next_begin_main_frame_to_reduce_latency_{};
23464   bool video_needs_begin_frames_{};
23465   bool defer_begin_main_frame_{};
23466   bool last_commit_had_no_updates_{};
23467   bool did_draw_in_last_frame_{};
23468   bool did_submit_in_last_frame_{};
23469   bool needs_impl_side_invalidation_{};
23470   bool current_pending_tree_is_impl_side_{};
23471   bool previous_pending_tree_was_impl_side_{};
23472   bool processing_animation_worklets_for_active_tree_{};
23473   bool processing_animation_worklets_for_pending_tree_{};
23474   bool processing_paint_worklets_for_pending_tree_{};
23475 
23476   // Allows to preserve unknown protobuf fields for compatibility
23477   // with future versions of .proto files.
23478   std::string unknown_fields_;
23479 
23480   std::bitset<47> _has_field_{};
23481 };
23482 
23483 
23484 class PERFETTO_EXPORT ChromeCompositorStateMachine_MajorState : public ::protozero::CppMessageObj {
23485  public:
23486   using BeginImplFrameState = ChromeCompositorStateMachine_MajorState_BeginImplFrameState;
23487   static constexpr auto BEGIN_IMPL_FRAME_UNSPECIFIED = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_UNSPECIFIED;
23488   static constexpr auto BEGIN_IMPL_FRAME_IDLE = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_IDLE;
23489   static constexpr auto BEGIN_IMPL_FRAME_INSIDE_BEGIN_FRAME = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_INSIDE_BEGIN_FRAME;
23490   static constexpr auto BEGIN_IMPL_FRAME_INSIDE_DEADLINE = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_INSIDE_DEADLINE;
23491   static constexpr auto BeginImplFrameState_MIN = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_UNSPECIFIED;
23492   static constexpr auto BeginImplFrameState_MAX = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_INSIDE_DEADLINE;
23493   using BeginMainFrameState = ChromeCompositorStateMachine_MajorState_BeginMainFrameState;
23494   static constexpr auto BEGIN_MAIN_FRAME_UNSPECIFIED = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_UNSPECIFIED;
23495   static constexpr auto BEGIN_MAIN_FRAME_IDLE = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_IDLE;
23496   static constexpr auto BEGIN_MAIN_FRAME_SENT = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_SENT;
23497   static constexpr auto BEGIN_MAIN_FRAME_READY_TO_COMMIT = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_READY_TO_COMMIT;
23498   static constexpr auto BeginMainFrameState_MIN = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_UNSPECIFIED;
23499   static constexpr auto BeginMainFrameState_MAX = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_READY_TO_COMMIT;
23500   using LayerTreeFrameSinkState = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState;
23501   static constexpr auto LAYER_TREE_FRAME_UNSPECIFIED = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_UNSPECIFIED;
23502   static constexpr auto LAYER_TREE_FRAME_NONE = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_NONE;
23503   static constexpr auto LAYER_TREE_FRAME_ACTIVE = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_ACTIVE;
23504   static constexpr auto LAYER_TREE_FRAME_CREATING = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_CREATING;
23505   static constexpr auto LAYER_TREE_FRAME_WAITING_FOR_FIRST_COMMIT = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_WAITING_FOR_FIRST_COMMIT;
23506   static constexpr auto LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION;
23507   static constexpr auto LayerTreeFrameSinkState_MIN = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_UNSPECIFIED;
23508   static constexpr auto LayerTreeFrameSinkState_MAX = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION;
23509   using ForcedRedrawOnTimeoutState = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState;
23510   static constexpr auto FORCED_REDRAW_UNSPECIFIED = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_UNSPECIFIED;
23511   static constexpr auto FORCED_REDRAW_IDLE = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_IDLE;
23512   static constexpr auto FORCED_REDRAW_WAITING_FOR_COMMIT = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_COMMIT;
23513   static constexpr auto FORCED_REDRAW_WAITING_FOR_ACTIVATION = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_ACTIVATION;
23514   static constexpr auto FORCED_REDRAW_WAITING_FOR_DRAW = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_DRAW;
23515   static constexpr auto ForcedRedrawOnTimeoutState_MIN = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_UNSPECIFIED;
23516   static constexpr auto ForcedRedrawOnTimeoutState_MAX = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_DRAW;
23517   enum FieldNumbers {
23518     kNextActionFieldNumber = 1,
23519     kBeginImplFrameStateFieldNumber = 2,
23520     kBeginMainFrameStateFieldNumber = 3,
23521     kLayerTreeFrameSinkStateFieldNumber = 4,
23522     kForcedRedrawStateFieldNumber = 5,
23523   };
23524 
23525   ChromeCompositorStateMachine_MajorState();
23526   ~ChromeCompositorStateMachine_MajorState() override;
23527   ChromeCompositorStateMachine_MajorState(ChromeCompositorStateMachine_MajorState&&) noexcept;
23528   ChromeCompositorStateMachine_MajorState& operator=(ChromeCompositorStateMachine_MajorState&&);
23529   ChromeCompositorStateMachine_MajorState(const ChromeCompositorStateMachine_MajorState&);
23530   ChromeCompositorStateMachine_MajorState& operator=(const ChromeCompositorStateMachine_MajorState&);
23531   bool operator==(const ChromeCompositorStateMachine_MajorState&) const;
operator !=(const ChromeCompositorStateMachine_MajorState & other) const23532   bool operator!=(const ChromeCompositorStateMachine_MajorState& other) const { return !(*this == other); }
23533 
23534   bool ParseFromArray(const void*, size_t) override;
23535   std::string SerializeAsString() const override;
23536   std::vector<uint8_t> SerializeAsArray() const override;
23537   void Serialize(::protozero::Message*) const;
23538 
has_next_action() const23539   bool has_next_action() const { return _has_field_[1]; }
next_action() const23540   ChromeCompositorSchedulerAction next_action() const { return next_action_; }
set_next_action(ChromeCompositorSchedulerAction value)23541   void set_next_action(ChromeCompositorSchedulerAction value) { next_action_ = value; _has_field_.set(1); }
23542 
has_begin_impl_frame_state() const23543   bool has_begin_impl_frame_state() const { return _has_field_[2]; }
begin_impl_frame_state() const23544   ChromeCompositorStateMachine_MajorState_BeginImplFrameState begin_impl_frame_state() const { return begin_impl_frame_state_; }
set_begin_impl_frame_state(ChromeCompositorStateMachine_MajorState_BeginImplFrameState value)23545   void set_begin_impl_frame_state(ChromeCompositorStateMachine_MajorState_BeginImplFrameState value) { begin_impl_frame_state_ = value; _has_field_.set(2); }
23546 
has_begin_main_frame_state() const23547   bool has_begin_main_frame_state() const { return _has_field_[3]; }
begin_main_frame_state() const23548   ChromeCompositorStateMachine_MajorState_BeginMainFrameState begin_main_frame_state() const { return begin_main_frame_state_; }
set_begin_main_frame_state(ChromeCompositorStateMachine_MajorState_BeginMainFrameState value)23549   void set_begin_main_frame_state(ChromeCompositorStateMachine_MajorState_BeginMainFrameState value) { begin_main_frame_state_ = value; _has_field_.set(3); }
23550 
has_layer_tree_frame_sink_state() const23551   bool has_layer_tree_frame_sink_state() const { return _has_field_[4]; }
layer_tree_frame_sink_state() const23552   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)23553   void set_layer_tree_frame_sink_state(ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState value) { layer_tree_frame_sink_state_ = value; _has_field_.set(4); }
23554 
has_forced_redraw_state() const23555   bool has_forced_redraw_state() const { return _has_field_[5]; }
forced_redraw_state() const23556   ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState forced_redraw_state() const { return forced_redraw_state_; }
set_forced_redraw_state(ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState value)23557   void set_forced_redraw_state(ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState value) { forced_redraw_state_ = value; _has_field_.set(5); }
23558 
23559  private:
23560   ChromeCompositorSchedulerAction next_action_{};
23561   ChromeCompositorStateMachine_MajorState_BeginImplFrameState begin_impl_frame_state_{};
23562   ChromeCompositorStateMachine_MajorState_BeginMainFrameState begin_main_frame_state_{};
23563   ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState layer_tree_frame_sink_state_{};
23564   ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState forced_redraw_state_{};
23565 
23566   // Allows to preserve unknown protobuf fields for compatibility
23567   // with future versions of .proto files.
23568   std::string unknown_fields_;
23569 
23570   std::bitset<6> _has_field_{};
23571 };
23572 
23573 
23574 class PERFETTO_EXPORT ChromeCompositorSchedulerState : public ::protozero::CppMessageObj {
23575  public:
23576   using BeginImplFrameDeadlineMode = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode;
23577   static constexpr auto DEADLINE_MODE_UNSPECIFIED = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_UNSPECIFIED;
23578   static constexpr auto DEADLINE_MODE_NONE = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_NONE;
23579   static constexpr auto DEADLINE_MODE_IMMEDIATE = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_IMMEDIATE;
23580   static constexpr auto DEADLINE_MODE_REGULAR = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_REGULAR;
23581   static constexpr auto DEADLINE_MODE_LATE = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_LATE;
23582   static constexpr auto DEADLINE_MODE_BLOCKED = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_BLOCKED;
23583   static constexpr auto BeginImplFrameDeadlineMode_MIN = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_UNSPECIFIED;
23584   static constexpr auto BeginImplFrameDeadlineMode_MAX = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_BLOCKED;
23585   enum FieldNumbers {
23586     kStateMachineFieldNumber = 1,
23587     kObservingBeginFrameSourceFieldNumber = 2,
23588     kBeginImplFrameDeadlineTaskFieldNumber = 3,
23589     kPendingBeginFrameTaskFieldNumber = 4,
23590     kSkippedLastFrameMissedExceededDeadlineFieldNumber = 5,
23591     kSkippedLastFrameToReduceLatencyFieldNumber = 6,
23592     kInsideActionFieldNumber = 7,
23593     kDeadlineModeFieldNumber = 8,
23594     kDeadlineUsFieldNumber = 9,
23595     kDeadlineScheduledAtUsFieldNumber = 10,
23596     kNowUsFieldNumber = 11,
23597     kNowToDeadlineDeltaUsFieldNumber = 12,
23598     kNowToDeadlineScheduledAtDeltaUsFieldNumber = 13,
23599     kBeginImplFrameArgsFieldNumber = 14,
23600     kBeginFrameObserverStateFieldNumber = 15,
23601     kBeginFrameSourceStateFieldNumber = 16,
23602     kCompositorTimingHistoryFieldNumber = 17,
23603   };
23604 
23605   ChromeCompositorSchedulerState();
23606   ~ChromeCompositorSchedulerState() override;
23607   ChromeCompositorSchedulerState(ChromeCompositorSchedulerState&&) noexcept;
23608   ChromeCompositorSchedulerState& operator=(ChromeCompositorSchedulerState&&);
23609   ChromeCompositorSchedulerState(const ChromeCompositorSchedulerState&);
23610   ChromeCompositorSchedulerState& operator=(const ChromeCompositorSchedulerState&);
23611   bool operator==(const ChromeCompositorSchedulerState&) const;
operator !=(const ChromeCompositorSchedulerState & other) const23612   bool operator!=(const ChromeCompositorSchedulerState& other) const { return !(*this == other); }
23613 
23614   bool ParseFromArray(const void*, size_t) override;
23615   std::string SerializeAsString() const override;
23616   std::vector<uint8_t> SerializeAsArray() const override;
23617   void Serialize(::protozero::Message*) const;
23618 
has_state_machine() const23619   bool has_state_machine() const { return _has_field_[1]; }
state_machine() const23620   const ChromeCompositorStateMachine& state_machine() const { return *state_machine_; }
mutable_state_machine()23621   ChromeCompositorStateMachine* mutable_state_machine() { _has_field_.set(1); return state_machine_.get(); }
23622 
has_observing_begin_frame_source() const23623   bool has_observing_begin_frame_source() const { return _has_field_[2]; }
observing_begin_frame_source() const23624   bool observing_begin_frame_source() const { return observing_begin_frame_source_; }
set_observing_begin_frame_source(bool value)23625   void set_observing_begin_frame_source(bool value) { observing_begin_frame_source_ = value; _has_field_.set(2); }
23626 
has_begin_impl_frame_deadline_task() const23627   bool has_begin_impl_frame_deadline_task() const { return _has_field_[3]; }
begin_impl_frame_deadline_task() const23628   bool begin_impl_frame_deadline_task() const { return begin_impl_frame_deadline_task_; }
set_begin_impl_frame_deadline_task(bool value)23629   void set_begin_impl_frame_deadline_task(bool value) { begin_impl_frame_deadline_task_ = value; _has_field_.set(3); }
23630 
has_pending_begin_frame_task() const23631   bool has_pending_begin_frame_task() const { return _has_field_[4]; }
pending_begin_frame_task() const23632   bool pending_begin_frame_task() const { return pending_begin_frame_task_; }
set_pending_begin_frame_task(bool value)23633   void set_pending_begin_frame_task(bool value) { pending_begin_frame_task_ = value; _has_field_.set(4); }
23634 
has_skipped_last_frame_missed_exceeded_deadline() const23635   bool has_skipped_last_frame_missed_exceeded_deadline() const { return _has_field_[5]; }
skipped_last_frame_missed_exceeded_deadline() const23636   bool skipped_last_frame_missed_exceeded_deadline() const { return skipped_last_frame_missed_exceeded_deadline_; }
set_skipped_last_frame_missed_exceeded_deadline(bool value)23637   void set_skipped_last_frame_missed_exceeded_deadline(bool value) { skipped_last_frame_missed_exceeded_deadline_ = value; _has_field_.set(5); }
23638 
has_skipped_last_frame_to_reduce_latency() const23639   bool has_skipped_last_frame_to_reduce_latency() const { return _has_field_[6]; }
skipped_last_frame_to_reduce_latency() const23640   bool skipped_last_frame_to_reduce_latency() const { return skipped_last_frame_to_reduce_latency_; }
set_skipped_last_frame_to_reduce_latency(bool value)23641   void set_skipped_last_frame_to_reduce_latency(bool value) { skipped_last_frame_to_reduce_latency_ = value; _has_field_.set(6); }
23642 
has_inside_action() const23643   bool has_inside_action() const { return _has_field_[7]; }
inside_action() const23644   ChromeCompositorSchedulerAction inside_action() const { return inside_action_; }
set_inside_action(ChromeCompositorSchedulerAction value)23645   void set_inside_action(ChromeCompositorSchedulerAction value) { inside_action_ = value; _has_field_.set(7); }
23646 
has_deadline_mode() const23647   bool has_deadline_mode() const { return _has_field_[8]; }
deadline_mode() const23648   ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode deadline_mode() const { return deadline_mode_; }
set_deadline_mode(ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode value)23649   void set_deadline_mode(ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode value) { deadline_mode_ = value; _has_field_.set(8); }
23650 
has_deadline_us() const23651   bool has_deadline_us() const { return _has_field_[9]; }
deadline_us() const23652   int64_t deadline_us() const { return deadline_us_; }
set_deadline_us(int64_t value)23653   void set_deadline_us(int64_t value) { deadline_us_ = value; _has_field_.set(9); }
23654 
has_deadline_scheduled_at_us() const23655   bool has_deadline_scheduled_at_us() const { return _has_field_[10]; }
deadline_scheduled_at_us() const23656   int64_t deadline_scheduled_at_us() const { return deadline_scheduled_at_us_; }
set_deadline_scheduled_at_us(int64_t value)23657   void set_deadline_scheduled_at_us(int64_t value) { deadline_scheduled_at_us_ = value; _has_field_.set(10); }
23658 
has_now_us() const23659   bool has_now_us() const { return _has_field_[11]; }
now_us() const23660   int64_t now_us() const { return now_us_; }
set_now_us(int64_t value)23661   void set_now_us(int64_t value) { now_us_ = value; _has_field_.set(11); }
23662 
has_now_to_deadline_delta_us() const23663   bool has_now_to_deadline_delta_us() const { return _has_field_[12]; }
now_to_deadline_delta_us() const23664   int64_t now_to_deadline_delta_us() const { return now_to_deadline_delta_us_; }
set_now_to_deadline_delta_us(int64_t value)23665   void set_now_to_deadline_delta_us(int64_t value) { now_to_deadline_delta_us_ = value; _has_field_.set(12); }
23666 
has_now_to_deadline_scheduled_at_delta_us() const23667   bool has_now_to_deadline_scheduled_at_delta_us() const { return _has_field_[13]; }
now_to_deadline_scheduled_at_delta_us() const23668   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)23669   void set_now_to_deadline_scheduled_at_delta_us(int64_t value) { now_to_deadline_scheduled_at_delta_us_ = value; _has_field_.set(13); }
23670 
has_begin_impl_frame_args() const23671   bool has_begin_impl_frame_args() const { return _has_field_[14]; }
begin_impl_frame_args() const23672   const BeginImplFrameArgs& begin_impl_frame_args() const { return *begin_impl_frame_args_; }
mutable_begin_impl_frame_args()23673   BeginImplFrameArgs* mutable_begin_impl_frame_args() { _has_field_.set(14); return begin_impl_frame_args_.get(); }
23674 
has_begin_frame_observer_state() const23675   bool has_begin_frame_observer_state() const { return _has_field_[15]; }
begin_frame_observer_state() const23676   const BeginFrameObserverState& begin_frame_observer_state() const { return *begin_frame_observer_state_; }
mutable_begin_frame_observer_state()23677   BeginFrameObserverState* mutable_begin_frame_observer_state() { _has_field_.set(15); return begin_frame_observer_state_.get(); }
23678 
has_begin_frame_source_state() const23679   bool has_begin_frame_source_state() const { return _has_field_[16]; }
begin_frame_source_state() const23680   const BeginFrameSourceState& begin_frame_source_state() const { return *begin_frame_source_state_; }
mutable_begin_frame_source_state()23681   BeginFrameSourceState* mutable_begin_frame_source_state() { _has_field_.set(16); return begin_frame_source_state_.get(); }
23682 
has_compositor_timing_history() const23683   bool has_compositor_timing_history() const { return _has_field_[17]; }
compositor_timing_history() const23684   const CompositorTimingHistory& compositor_timing_history() const { return *compositor_timing_history_; }
mutable_compositor_timing_history()23685   CompositorTimingHistory* mutable_compositor_timing_history() { _has_field_.set(17); return compositor_timing_history_.get(); }
23686 
23687  private:
23688   ::protozero::CopyablePtr<ChromeCompositorStateMachine> state_machine_;
23689   bool observing_begin_frame_source_{};
23690   bool begin_impl_frame_deadline_task_{};
23691   bool pending_begin_frame_task_{};
23692   bool skipped_last_frame_missed_exceeded_deadline_{};
23693   bool skipped_last_frame_to_reduce_latency_{};
23694   ChromeCompositorSchedulerAction inside_action_{};
23695   ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode deadline_mode_{};
23696   int64_t deadline_us_{};
23697   int64_t deadline_scheduled_at_us_{};
23698   int64_t now_us_{};
23699   int64_t now_to_deadline_delta_us_{};
23700   int64_t now_to_deadline_scheduled_at_delta_us_{};
23701   ::protozero::CopyablePtr<BeginImplFrameArgs> begin_impl_frame_args_;
23702   ::protozero::CopyablePtr<BeginFrameObserverState> begin_frame_observer_state_;
23703   ::protozero::CopyablePtr<BeginFrameSourceState> begin_frame_source_state_;
23704   ::protozero::CopyablePtr<CompositorTimingHistory> compositor_timing_history_;
23705 
23706   // Allows to preserve unknown protobuf fields for compatibility
23707   // with future versions of .proto files.
23708   std::string unknown_fields_;
23709 
23710   std::bitset<18> _has_field_{};
23711 };
23712 
23713 }  // namespace perfetto
23714 }  // namespace protos
23715 }  // namespace gen
23716 
23717 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_COMPOSITOR_SCHEDULER_STATE_PROTO_CPP_H_
23718 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/source_location.gen.h
23719 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
23720 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_SOURCE_LOCATION_PROTO_CPP_H_
23721 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_SOURCE_LOCATION_PROTO_CPP_H_
23722 
23723 #include <stdint.h>
23724 #include <bitset>
23725 #include <vector>
23726 #include <string>
23727 #include <type_traits>
23728 
23729 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
23730 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
23731 // gen_amalgamated expanded: #include "perfetto/base/export.h"
23732 
23733 namespace perfetto {
23734 namespace protos {
23735 namespace gen {
23736 class SourceLocation;
23737 }  // namespace perfetto
23738 }  // namespace protos
23739 }  // namespace gen
23740 
23741 namespace protozero {
23742 class Message;
23743 }  // namespace protozero
23744 
23745 namespace perfetto {
23746 namespace protos {
23747 namespace gen {
23748 
23749 class PERFETTO_EXPORT SourceLocation : public ::protozero::CppMessageObj {
23750  public:
23751   enum FieldNumbers {
23752     kIidFieldNumber = 1,
23753     kFileNameFieldNumber = 2,
23754     kFunctionNameFieldNumber = 3,
23755     kLineNumberFieldNumber = 4,
23756   };
23757 
23758   SourceLocation();
23759   ~SourceLocation() override;
23760   SourceLocation(SourceLocation&&) noexcept;
23761   SourceLocation& operator=(SourceLocation&&);
23762   SourceLocation(const SourceLocation&);
23763   SourceLocation& operator=(const SourceLocation&);
23764   bool operator==(const SourceLocation&) const;
operator !=(const SourceLocation & other) const23765   bool operator!=(const SourceLocation& other) const { return !(*this == other); }
23766 
23767   bool ParseFromArray(const void*, size_t) override;
23768   std::string SerializeAsString() const override;
23769   std::vector<uint8_t> SerializeAsArray() const override;
23770   void Serialize(::protozero::Message*) const;
23771 
has_iid() const23772   bool has_iid() const { return _has_field_[1]; }
iid() const23773   uint64_t iid() const { return iid_; }
set_iid(uint64_t value)23774   void set_iid(uint64_t value) { iid_ = value; _has_field_.set(1); }
23775 
has_file_name() const23776   bool has_file_name() const { return _has_field_[2]; }
file_name() const23777   const std::string& file_name() const { return file_name_; }
set_file_name(const std::string & value)23778   void set_file_name(const std::string& value) { file_name_ = value; _has_field_.set(2); }
23779 
has_function_name() const23780   bool has_function_name() const { return _has_field_[3]; }
function_name() const23781   const std::string& function_name() const { return function_name_; }
set_function_name(const std::string & value)23782   void set_function_name(const std::string& value) { function_name_ = value; _has_field_.set(3); }
23783 
has_line_number() const23784   bool has_line_number() const { return _has_field_[4]; }
line_number() const23785   uint32_t line_number() const { return line_number_; }
set_line_number(uint32_t value)23786   void set_line_number(uint32_t value) { line_number_ = value; _has_field_.set(4); }
23787 
23788  private:
23789   uint64_t iid_{};
23790   std::string file_name_{};
23791   std::string function_name_{};
23792   uint32_t line_number_{};
23793 
23794   // Allows to preserve unknown protobuf fields for compatibility
23795   // with future versions of .proto files.
23796   std::string unknown_fields_;
23797 
23798   std::bitset<5> _has_field_{};
23799 };
23800 
23801 }  // namespace perfetto
23802 }  // namespace protos
23803 }  // namespace gen
23804 
23805 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_SOURCE_LOCATION_PROTO_CPP_H_
23806 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
23807 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
23808 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
23809 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
23810 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
23811 #if defined(__GNUC__) || defined(__clang__)
23812 #pragma GCC diagnostic push
23813 #pragma GCC diagnostic ignored "-Wfloat-equal"
23814 #endif
23815 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.gen.h"
23816 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/source_location.gen.h"
23817 
23818 namespace perfetto {
23819 namespace protos {
23820 namespace gen {
23821 
23822 CompositorTimingHistory::CompositorTimingHistory() = default;
23823 CompositorTimingHistory::~CompositorTimingHistory() = default;
23824 CompositorTimingHistory::CompositorTimingHistory(const CompositorTimingHistory&) = default;
23825 CompositorTimingHistory& CompositorTimingHistory::operator=(const CompositorTimingHistory&) = default;
23826 CompositorTimingHistory::CompositorTimingHistory(CompositorTimingHistory&&) noexcept = default;
23827 CompositorTimingHistory& CompositorTimingHistory::operator=(CompositorTimingHistory&&) = default;
23828 
operator ==(const CompositorTimingHistory & other) const23829 bool CompositorTimingHistory::operator==(const CompositorTimingHistory& other) const {
23830   return unknown_fields_ == other.unknown_fields_
23831    && begin_main_frame_queue_critical_estimate_delta_us_ == other.begin_main_frame_queue_critical_estimate_delta_us_
23832    && begin_main_frame_queue_not_critical_estimate_delta_us_ == other.begin_main_frame_queue_not_critical_estimate_delta_us_
23833    && begin_main_frame_start_to_ready_to_commit_estimate_delta_us_ == other.begin_main_frame_start_to_ready_to_commit_estimate_delta_us_
23834    && commit_to_ready_to_activate_estimate_delta_us_ == other.commit_to_ready_to_activate_estimate_delta_us_
23835    && prepare_tiles_estimate_delta_us_ == other.prepare_tiles_estimate_delta_us_
23836    && activate_estimate_delta_us_ == other.activate_estimate_delta_us_
23837    && draw_estimate_delta_us_ == other.draw_estimate_delta_us_;
23838 }
23839 
ParseFromArray(const void * raw,size_t size)23840 bool CompositorTimingHistory::ParseFromArray(const void* raw, size_t size) {
23841   unknown_fields_.clear();
23842   bool packed_error = false;
23843 
23844   ::protozero::ProtoDecoder dec(raw, size);
23845   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
23846     if (field.id() < _has_field_.size()) {
23847       _has_field_.set(field.id());
23848     }
23849     switch (field.id()) {
23850       case 1 /* begin_main_frame_queue_critical_estimate_delta_us */:
23851         field.get(&begin_main_frame_queue_critical_estimate_delta_us_);
23852         break;
23853       case 2 /* begin_main_frame_queue_not_critical_estimate_delta_us */:
23854         field.get(&begin_main_frame_queue_not_critical_estimate_delta_us_);
23855         break;
23856       case 3 /* begin_main_frame_start_to_ready_to_commit_estimate_delta_us */:
23857         field.get(&begin_main_frame_start_to_ready_to_commit_estimate_delta_us_);
23858         break;
23859       case 4 /* commit_to_ready_to_activate_estimate_delta_us */:
23860         field.get(&commit_to_ready_to_activate_estimate_delta_us_);
23861         break;
23862       case 5 /* prepare_tiles_estimate_delta_us */:
23863         field.get(&prepare_tiles_estimate_delta_us_);
23864         break;
23865       case 6 /* activate_estimate_delta_us */:
23866         field.get(&activate_estimate_delta_us_);
23867         break;
23868       case 7 /* draw_estimate_delta_us */:
23869         field.get(&draw_estimate_delta_us_);
23870         break;
23871       default:
23872         field.SerializeAndAppendTo(&unknown_fields_);
23873         break;
23874     }
23875   }
23876   return !packed_error && !dec.bytes_left();
23877 }
23878 
SerializeAsString() const23879 std::string CompositorTimingHistory::SerializeAsString() const {
23880   ::protozero::HeapBuffered<::protozero::Message> msg;
23881   Serialize(msg.get());
23882   return msg.SerializeAsString();
23883 }
23884 
SerializeAsArray() const23885 std::vector<uint8_t> CompositorTimingHistory::SerializeAsArray() const {
23886   ::protozero::HeapBuffered<::protozero::Message> msg;
23887   Serialize(msg.get());
23888   return msg.SerializeAsArray();
23889 }
23890 
Serialize(::protozero::Message * msg) const23891 void CompositorTimingHistory::Serialize(::protozero::Message* msg) const {
23892   // Field 1: begin_main_frame_queue_critical_estimate_delta_us
23893   if (_has_field_[1]) {
23894     msg->AppendVarInt(1, begin_main_frame_queue_critical_estimate_delta_us_);
23895   }
23896 
23897   // Field 2: begin_main_frame_queue_not_critical_estimate_delta_us
23898   if (_has_field_[2]) {
23899     msg->AppendVarInt(2, begin_main_frame_queue_not_critical_estimate_delta_us_);
23900   }
23901 
23902   // Field 3: begin_main_frame_start_to_ready_to_commit_estimate_delta_us
23903   if (_has_field_[3]) {
23904     msg->AppendVarInt(3, begin_main_frame_start_to_ready_to_commit_estimate_delta_us_);
23905   }
23906 
23907   // Field 4: commit_to_ready_to_activate_estimate_delta_us
23908   if (_has_field_[4]) {
23909     msg->AppendVarInt(4, commit_to_ready_to_activate_estimate_delta_us_);
23910   }
23911 
23912   // Field 5: prepare_tiles_estimate_delta_us
23913   if (_has_field_[5]) {
23914     msg->AppendVarInt(5, prepare_tiles_estimate_delta_us_);
23915   }
23916 
23917   // Field 6: activate_estimate_delta_us
23918   if (_has_field_[6]) {
23919     msg->AppendVarInt(6, activate_estimate_delta_us_);
23920   }
23921 
23922   // Field 7: draw_estimate_delta_us
23923   if (_has_field_[7]) {
23924     msg->AppendVarInt(7, draw_estimate_delta_us_);
23925   }
23926 
23927   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
23928 }
23929 
23930 
23931 BeginFrameSourceState::BeginFrameSourceState() = default;
23932 BeginFrameSourceState::~BeginFrameSourceState() = default;
23933 BeginFrameSourceState::BeginFrameSourceState(const BeginFrameSourceState&) = default;
23934 BeginFrameSourceState& BeginFrameSourceState::operator=(const BeginFrameSourceState&) = default;
23935 BeginFrameSourceState::BeginFrameSourceState(BeginFrameSourceState&&) noexcept = default;
23936 BeginFrameSourceState& BeginFrameSourceState::operator=(BeginFrameSourceState&&) = default;
23937 
operator ==(const BeginFrameSourceState & other) const23938 bool BeginFrameSourceState::operator==(const BeginFrameSourceState& other) const {
23939   return unknown_fields_ == other.unknown_fields_
23940    && source_id_ == other.source_id_
23941    && paused_ == other.paused_
23942    && num_observers_ == other.num_observers_
23943    && last_begin_frame_args_ == other.last_begin_frame_args_;
23944 }
23945 
ParseFromArray(const void * raw,size_t size)23946 bool BeginFrameSourceState::ParseFromArray(const void* raw, size_t size) {
23947   unknown_fields_.clear();
23948   bool packed_error = false;
23949 
23950   ::protozero::ProtoDecoder dec(raw, size);
23951   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
23952     if (field.id() < _has_field_.size()) {
23953       _has_field_.set(field.id());
23954     }
23955     switch (field.id()) {
23956       case 1 /* source_id */:
23957         field.get(&source_id_);
23958         break;
23959       case 2 /* paused */:
23960         field.get(&paused_);
23961         break;
23962       case 3 /* num_observers */:
23963         field.get(&num_observers_);
23964         break;
23965       case 4 /* last_begin_frame_args */:
23966         (*last_begin_frame_args_).ParseFromArray(field.data(), field.size());
23967         break;
23968       default:
23969         field.SerializeAndAppendTo(&unknown_fields_);
23970         break;
23971     }
23972   }
23973   return !packed_error && !dec.bytes_left();
23974 }
23975 
SerializeAsString() const23976 std::string BeginFrameSourceState::SerializeAsString() const {
23977   ::protozero::HeapBuffered<::protozero::Message> msg;
23978   Serialize(msg.get());
23979   return msg.SerializeAsString();
23980 }
23981 
SerializeAsArray() const23982 std::vector<uint8_t> BeginFrameSourceState::SerializeAsArray() const {
23983   ::protozero::HeapBuffered<::protozero::Message> msg;
23984   Serialize(msg.get());
23985   return msg.SerializeAsArray();
23986 }
23987 
Serialize(::protozero::Message * msg) const23988 void BeginFrameSourceState::Serialize(::protozero::Message* msg) const {
23989   // Field 1: source_id
23990   if (_has_field_[1]) {
23991     msg->AppendVarInt(1, source_id_);
23992   }
23993 
23994   // Field 2: paused
23995   if (_has_field_[2]) {
23996     msg->AppendTinyVarInt(2, paused_);
23997   }
23998 
23999   // Field 3: num_observers
24000   if (_has_field_[3]) {
24001     msg->AppendVarInt(3, num_observers_);
24002   }
24003 
24004   // Field 4: last_begin_frame_args
24005   if (_has_field_[4]) {
24006     (*last_begin_frame_args_).Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
24007   }
24008 
24009   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
24010 }
24011 
24012 
24013 BeginFrameArgs::BeginFrameArgs() = default;
24014 BeginFrameArgs::~BeginFrameArgs() = default;
24015 BeginFrameArgs::BeginFrameArgs(const BeginFrameArgs&) = default;
24016 BeginFrameArgs& BeginFrameArgs::operator=(const BeginFrameArgs&) = default;
24017 BeginFrameArgs::BeginFrameArgs(BeginFrameArgs&&) noexcept = default;
24018 BeginFrameArgs& BeginFrameArgs::operator=(BeginFrameArgs&&) = default;
24019 
operator ==(const BeginFrameArgs & other) const24020 bool BeginFrameArgs::operator==(const BeginFrameArgs& other) const {
24021   return unknown_fields_ == other.unknown_fields_
24022    && type_ == other.type_
24023    && source_id_ == other.source_id_
24024    && sequence_number_ == other.sequence_number_
24025    && frame_time_us_ == other.frame_time_us_
24026    && deadline_us_ == other.deadline_us_
24027    && interval_delta_us_ == other.interval_delta_us_
24028    && on_critical_path_ == other.on_critical_path_
24029    && animate_only_ == other.animate_only_
24030    && source_location_iid_ == other.source_location_iid_
24031    && source_location_ == other.source_location_;
24032 }
24033 
ParseFromArray(const void * raw,size_t size)24034 bool BeginFrameArgs::ParseFromArray(const void* raw, size_t size) {
24035   unknown_fields_.clear();
24036   bool packed_error = false;
24037 
24038   ::protozero::ProtoDecoder dec(raw, size);
24039   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
24040     if (field.id() < _has_field_.size()) {
24041       _has_field_.set(field.id());
24042     }
24043     switch (field.id()) {
24044       case 1 /* type */:
24045         field.get(&type_);
24046         break;
24047       case 2 /* source_id */:
24048         field.get(&source_id_);
24049         break;
24050       case 3 /* sequence_number */:
24051         field.get(&sequence_number_);
24052         break;
24053       case 4 /* frame_time_us */:
24054         field.get(&frame_time_us_);
24055         break;
24056       case 5 /* deadline_us */:
24057         field.get(&deadline_us_);
24058         break;
24059       case 6 /* interval_delta_us */:
24060         field.get(&interval_delta_us_);
24061         break;
24062       case 7 /* on_critical_path */:
24063         field.get(&on_critical_path_);
24064         break;
24065       case 8 /* animate_only */:
24066         field.get(&animate_only_);
24067         break;
24068       case 9 /* source_location_iid */:
24069         field.get(&source_location_iid_);
24070         break;
24071       case 10 /* source_location */:
24072         (*source_location_).ParseFromArray(field.data(), field.size());
24073         break;
24074       default:
24075         field.SerializeAndAppendTo(&unknown_fields_);
24076         break;
24077     }
24078   }
24079   return !packed_error && !dec.bytes_left();
24080 }
24081 
SerializeAsString() const24082 std::string BeginFrameArgs::SerializeAsString() const {
24083   ::protozero::HeapBuffered<::protozero::Message> msg;
24084   Serialize(msg.get());
24085   return msg.SerializeAsString();
24086 }
24087 
SerializeAsArray() const24088 std::vector<uint8_t> BeginFrameArgs::SerializeAsArray() const {
24089   ::protozero::HeapBuffered<::protozero::Message> msg;
24090   Serialize(msg.get());
24091   return msg.SerializeAsArray();
24092 }
24093 
Serialize(::protozero::Message * msg) const24094 void BeginFrameArgs::Serialize(::protozero::Message* msg) const {
24095   // Field 1: type
24096   if (_has_field_[1]) {
24097     msg->AppendVarInt(1, type_);
24098   }
24099 
24100   // Field 2: source_id
24101   if (_has_field_[2]) {
24102     msg->AppendVarInt(2, source_id_);
24103   }
24104 
24105   // Field 3: sequence_number
24106   if (_has_field_[3]) {
24107     msg->AppendVarInt(3, sequence_number_);
24108   }
24109 
24110   // Field 4: frame_time_us
24111   if (_has_field_[4]) {
24112     msg->AppendVarInt(4, frame_time_us_);
24113   }
24114 
24115   // Field 5: deadline_us
24116   if (_has_field_[5]) {
24117     msg->AppendVarInt(5, deadline_us_);
24118   }
24119 
24120   // Field 6: interval_delta_us
24121   if (_has_field_[6]) {
24122     msg->AppendVarInt(6, interval_delta_us_);
24123   }
24124 
24125   // Field 7: on_critical_path
24126   if (_has_field_[7]) {
24127     msg->AppendTinyVarInt(7, on_critical_path_);
24128   }
24129 
24130   // Field 8: animate_only
24131   if (_has_field_[8]) {
24132     msg->AppendTinyVarInt(8, animate_only_);
24133   }
24134 
24135   // Field 9: source_location_iid
24136   if (_has_field_[9]) {
24137     msg->AppendVarInt(9, source_location_iid_);
24138   }
24139 
24140   // Field 10: source_location
24141   if (_has_field_[10]) {
24142     (*source_location_).Serialize(msg->BeginNestedMessage<::protozero::Message>(10));
24143   }
24144 
24145   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
24146 }
24147 
24148 
24149 BeginFrameObserverState::BeginFrameObserverState() = default;
24150 BeginFrameObserverState::~BeginFrameObserverState() = default;
24151 BeginFrameObserverState::BeginFrameObserverState(const BeginFrameObserverState&) = default;
24152 BeginFrameObserverState& BeginFrameObserverState::operator=(const BeginFrameObserverState&) = default;
24153 BeginFrameObserverState::BeginFrameObserverState(BeginFrameObserverState&&) noexcept = default;
24154 BeginFrameObserverState& BeginFrameObserverState::operator=(BeginFrameObserverState&&) = default;
24155 
operator ==(const BeginFrameObserverState & other) const24156 bool BeginFrameObserverState::operator==(const BeginFrameObserverState& other) const {
24157   return unknown_fields_ == other.unknown_fields_
24158    && dropped_begin_frame_args_ == other.dropped_begin_frame_args_
24159    && last_begin_frame_args_ == other.last_begin_frame_args_;
24160 }
24161 
ParseFromArray(const void * raw,size_t size)24162 bool BeginFrameObserverState::ParseFromArray(const void* raw, size_t size) {
24163   unknown_fields_.clear();
24164   bool packed_error = false;
24165 
24166   ::protozero::ProtoDecoder dec(raw, size);
24167   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
24168     if (field.id() < _has_field_.size()) {
24169       _has_field_.set(field.id());
24170     }
24171     switch (field.id()) {
24172       case 1 /* dropped_begin_frame_args */:
24173         field.get(&dropped_begin_frame_args_);
24174         break;
24175       case 2 /* last_begin_frame_args */:
24176         (*last_begin_frame_args_).ParseFromArray(field.data(), field.size());
24177         break;
24178       default:
24179         field.SerializeAndAppendTo(&unknown_fields_);
24180         break;
24181     }
24182   }
24183   return !packed_error && !dec.bytes_left();
24184 }
24185 
SerializeAsString() const24186 std::string BeginFrameObserverState::SerializeAsString() const {
24187   ::protozero::HeapBuffered<::protozero::Message> msg;
24188   Serialize(msg.get());
24189   return msg.SerializeAsString();
24190 }
24191 
SerializeAsArray() const24192 std::vector<uint8_t> BeginFrameObserverState::SerializeAsArray() const {
24193   ::protozero::HeapBuffered<::protozero::Message> msg;
24194   Serialize(msg.get());
24195   return msg.SerializeAsArray();
24196 }
24197 
Serialize(::protozero::Message * msg) const24198 void BeginFrameObserverState::Serialize(::protozero::Message* msg) const {
24199   // Field 1: dropped_begin_frame_args
24200   if (_has_field_[1]) {
24201     msg->AppendVarInt(1, dropped_begin_frame_args_);
24202   }
24203 
24204   // Field 2: last_begin_frame_args
24205   if (_has_field_[2]) {
24206     (*last_begin_frame_args_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
24207   }
24208 
24209   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
24210 }
24211 
24212 
24213 BeginImplFrameArgs::BeginImplFrameArgs() = default;
24214 BeginImplFrameArgs::~BeginImplFrameArgs() = default;
24215 BeginImplFrameArgs::BeginImplFrameArgs(const BeginImplFrameArgs&) = default;
24216 BeginImplFrameArgs& BeginImplFrameArgs::operator=(const BeginImplFrameArgs&) = default;
24217 BeginImplFrameArgs::BeginImplFrameArgs(BeginImplFrameArgs&&) noexcept = default;
24218 BeginImplFrameArgs& BeginImplFrameArgs::operator=(BeginImplFrameArgs&&) = default;
24219 
operator ==(const BeginImplFrameArgs & other) const24220 bool BeginImplFrameArgs::operator==(const BeginImplFrameArgs& other) const {
24221   return unknown_fields_ == other.unknown_fields_
24222    && updated_at_us_ == other.updated_at_us_
24223    && finished_at_us_ == other.finished_at_us_
24224    && state_ == other.state_
24225    && current_args_ == other.current_args_
24226    && last_args_ == other.last_args_
24227    && timestamps_in_us_ == other.timestamps_in_us_;
24228 }
24229 
ParseFromArray(const void * raw,size_t size)24230 bool BeginImplFrameArgs::ParseFromArray(const void* raw, size_t size) {
24231   unknown_fields_.clear();
24232   bool packed_error = false;
24233 
24234   ::protozero::ProtoDecoder dec(raw, size);
24235   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
24236     if (field.id() < _has_field_.size()) {
24237       _has_field_.set(field.id());
24238     }
24239     switch (field.id()) {
24240       case 1 /* updated_at_us */:
24241         field.get(&updated_at_us_);
24242         break;
24243       case 2 /* finished_at_us */:
24244         field.get(&finished_at_us_);
24245         break;
24246       case 3 /* state */:
24247         field.get(&state_);
24248         break;
24249       case 4 /* current_args */:
24250         (*current_args_).ParseFromArray(field.data(), field.size());
24251         break;
24252       case 5 /* last_args */:
24253         (*last_args_).ParseFromArray(field.data(), field.size());
24254         break;
24255       case 6 /* timestamps_in_us */:
24256         (*timestamps_in_us_).ParseFromArray(field.data(), field.size());
24257         break;
24258       default:
24259         field.SerializeAndAppendTo(&unknown_fields_);
24260         break;
24261     }
24262   }
24263   return !packed_error && !dec.bytes_left();
24264 }
24265 
SerializeAsString() const24266 std::string BeginImplFrameArgs::SerializeAsString() const {
24267   ::protozero::HeapBuffered<::protozero::Message> msg;
24268   Serialize(msg.get());
24269   return msg.SerializeAsString();
24270 }
24271 
SerializeAsArray() const24272 std::vector<uint8_t> BeginImplFrameArgs::SerializeAsArray() const {
24273   ::protozero::HeapBuffered<::protozero::Message> msg;
24274   Serialize(msg.get());
24275   return msg.SerializeAsArray();
24276 }
24277 
Serialize(::protozero::Message * msg) const24278 void BeginImplFrameArgs::Serialize(::protozero::Message* msg) const {
24279   // Field 1: updated_at_us
24280   if (_has_field_[1]) {
24281     msg->AppendVarInt(1, updated_at_us_);
24282   }
24283 
24284   // Field 2: finished_at_us
24285   if (_has_field_[2]) {
24286     msg->AppendVarInt(2, finished_at_us_);
24287   }
24288 
24289   // Field 3: state
24290   if (_has_field_[3]) {
24291     msg->AppendVarInt(3, state_);
24292   }
24293 
24294   // Field 4: current_args
24295   if (_has_field_[4]) {
24296     (*current_args_).Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
24297   }
24298 
24299   // Field 5: last_args
24300   if (_has_field_[5]) {
24301     (*last_args_).Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
24302   }
24303 
24304   // Field 6: timestamps_in_us
24305   if (_has_field_[6]) {
24306     (*timestamps_in_us_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
24307   }
24308 
24309   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
24310 }
24311 
24312 
24313 BeginImplFrameArgs_TimestampsInUs::BeginImplFrameArgs_TimestampsInUs() = default;
24314 BeginImplFrameArgs_TimestampsInUs::~BeginImplFrameArgs_TimestampsInUs() = default;
24315 BeginImplFrameArgs_TimestampsInUs::BeginImplFrameArgs_TimestampsInUs(const BeginImplFrameArgs_TimestampsInUs&) = default;
24316 BeginImplFrameArgs_TimestampsInUs& BeginImplFrameArgs_TimestampsInUs::operator=(const BeginImplFrameArgs_TimestampsInUs&) = default;
24317 BeginImplFrameArgs_TimestampsInUs::BeginImplFrameArgs_TimestampsInUs(BeginImplFrameArgs_TimestampsInUs&&) noexcept = default;
24318 BeginImplFrameArgs_TimestampsInUs& BeginImplFrameArgs_TimestampsInUs::operator=(BeginImplFrameArgs_TimestampsInUs&&) = default;
24319 
operator ==(const BeginImplFrameArgs_TimestampsInUs & other) const24320 bool BeginImplFrameArgs_TimestampsInUs::operator==(const BeginImplFrameArgs_TimestampsInUs& other) const {
24321   return unknown_fields_ == other.unknown_fields_
24322    && interval_delta_ == other.interval_delta_
24323    && now_to_deadline_delta_ == other.now_to_deadline_delta_
24324    && frame_time_to_now_delta_ == other.frame_time_to_now_delta_
24325    && frame_time_to_deadline_delta_ == other.frame_time_to_deadline_delta_
24326    && now_ == other.now_
24327    && frame_time_ == other.frame_time_
24328    && deadline_ == other.deadline_;
24329 }
24330 
ParseFromArray(const void * raw,size_t size)24331 bool BeginImplFrameArgs_TimestampsInUs::ParseFromArray(const void* raw, size_t size) {
24332   unknown_fields_.clear();
24333   bool packed_error = false;
24334 
24335   ::protozero::ProtoDecoder dec(raw, size);
24336   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
24337     if (field.id() < _has_field_.size()) {
24338       _has_field_.set(field.id());
24339     }
24340     switch (field.id()) {
24341       case 1 /* interval_delta */:
24342         field.get(&interval_delta_);
24343         break;
24344       case 2 /* now_to_deadline_delta */:
24345         field.get(&now_to_deadline_delta_);
24346         break;
24347       case 3 /* frame_time_to_now_delta */:
24348         field.get(&frame_time_to_now_delta_);
24349         break;
24350       case 4 /* frame_time_to_deadline_delta */:
24351         field.get(&frame_time_to_deadline_delta_);
24352         break;
24353       case 5 /* now */:
24354         field.get(&now_);
24355         break;
24356       case 6 /* frame_time */:
24357         field.get(&frame_time_);
24358         break;
24359       case 7 /* deadline */:
24360         field.get(&deadline_);
24361         break;
24362       default:
24363         field.SerializeAndAppendTo(&unknown_fields_);
24364         break;
24365     }
24366   }
24367   return !packed_error && !dec.bytes_left();
24368 }
24369 
SerializeAsString() const24370 std::string BeginImplFrameArgs_TimestampsInUs::SerializeAsString() const {
24371   ::protozero::HeapBuffered<::protozero::Message> msg;
24372   Serialize(msg.get());
24373   return msg.SerializeAsString();
24374 }
24375 
SerializeAsArray() const24376 std::vector<uint8_t> BeginImplFrameArgs_TimestampsInUs::SerializeAsArray() const {
24377   ::protozero::HeapBuffered<::protozero::Message> msg;
24378   Serialize(msg.get());
24379   return msg.SerializeAsArray();
24380 }
24381 
Serialize(::protozero::Message * msg) const24382 void BeginImplFrameArgs_TimestampsInUs::Serialize(::protozero::Message* msg) const {
24383   // Field 1: interval_delta
24384   if (_has_field_[1]) {
24385     msg->AppendVarInt(1, interval_delta_);
24386   }
24387 
24388   // Field 2: now_to_deadline_delta
24389   if (_has_field_[2]) {
24390     msg->AppendVarInt(2, now_to_deadline_delta_);
24391   }
24392 
24393   // Field 3: frame_time_to_now_delta
24394   if (_has_field_[3]) {
24395     msg->AppendVarInt(3, frame_time_to_now_delta_);
24396   }
24397 
24398   // Field 4: frame_time_to_deadline_delta
24399   if (_has_field_[4]) {
24400     msg->AppendVarInt(4, frame_time_to_deadline_delta_);
24401   }
24402 
24403   // Field 5: now
24404   if (_has_field_[5]) {
24405     msg->AppendVarInt(5, now_);
24406   }
24407 
24408   // Field 6: frame_time
24409   if (_has_field_[6]) {
24410     msg->AppendVarInt(6, frame_time_);
24411   }
24412 
24413   // Field 7: deadline
24414   if (_has_field_[7]) {
24415     msg->AppendVarInt(7, deadline_);
24416   }
24417 
24418   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
24419 }
24420 
24421 
24422 ChromeCompositorStateMachine::ChromeCompositorStateMachine() = default;
24423 ChromeCompositorStateMachine::~ChromeCompositorStateMachine() = default;
24424 ChromeCompositorStateMachine::ChromeCompositorStateMachine(const ChromeCompositorStateMachine&) = default;
24425 ChromeCompositorStateMachine& ChromeCompositorStateMachine::operator=(const ChromeCompositorStateMachine&) = default;
24426 ChromeCompositorStateMachine::ChromeCompositorStateMachine(ChromeCompositorStateMachine&&) noexcept = default;
24427 ChromeCompositorStateMachine& ChromeCompositorStateMachine::operator=(ChromeCompositorStateMachine&&) = default;
24428 
operator ==(const ChromeCompositorStateMachine & other) const24429 bool ChromeCompositorStateMachine::operator==(const ChromeCompositorStateMachine& other) const {
24430   return unknown_fields_ == other.unknown_fields_
24431    && major_state_ == other.major_state_
24432    && minor_state_ == other.minor_state_;
24433 }
24434 
ParseFromArray(const void * raw,size_t size)24435 bool ChromeCompositorStateMachine::ParseFromArray(const void* raw, size_t size) {
24436   unknown_fields_.clear();
24437   bool packed_error = false;
24438 
24439   ::protozero::ProtoDecoder dec(raw, size);
24440   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
24441     if (field.id() < _has_field_.size()) {
24442       _has_field_.set(field.id());
24443     }
24444     switch (field.id()) {
24445       case 1 /* major_state */:
24446         (*major_state_).ParseFromArray(field.data(), field.size());
24447         break;
24448       case 2 /* minor_state */:
24449         (*minor_state_).ParseFromArray(field.data(), field.size());
24450         break;
24451       default:
24452         field.SerializeAndAppendTo(&unknown_fields_);
24453         break;
24454     }
24455   }
24456   return !packed_error && !dec.bytes_left();
24457 }
24458 
SerializeAsString() const24459 std::string ChromeCompositorStateMachine::SerializeAsString() const {
24460   ::protozero::HeapBuffered<::protozero::Message> msg;
24461   Serialize(msg.get());
24462   return msg.SerializeAsString();
24463 }
24464 
SerializeAsArray() const24465 std::vector<uint8_t> ChromeCompositorStateMachine::SerializeAsArray() const {
24466   ::protozero::HeapBuffered<::protozero::Message> msg;
24467   Serialize(msg.get());
24468   return msg.SerializeAsArray();
24469 }
24470 
Serialize(::protozero::Message * msg) const24471 void ChromeCompositorStateMachine::Serialize(::protozero::Message* msg) const {
24472   // Field 1: major_state
24473   if (_has_field_[1]) {
24474     (*major_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
24475   }
24476 
24477   // Field 2: minor_state
24478   if (_has_field_[2]) {
24479     (*minor_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
24480   }
24481 
24482   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
24483 }
24484 
24485 
24486 ChromeCompositorStateMachine_MinorState::ChromeCompositorStateMachine_MinorState() = default;
24487 ChromeCompositorStateMachine_MinorState::~ChromeCompositorStateMachine_MinorState() = default;
24488 ChromeCompositorStateMachine_MinorState::ChromeCompositorStateMachine_MinorState(const ChromeCompositorStateMachine_MinorState&) = default;
24489 ChromeCompositorStateMachine_MinorState& ChromeCompositorStateMachine_MinorState::operator=(const ChromeCompositorStateMachine_MinorState&) = default;
24490 ChromeCompositorStateMachine_MinorState::ChromeCompositorStateMachine_MinorState(ChromeCompositorStateMachine_MinorState&&) noexcept = default;
24491 ChromeCompositorStateMachine_MinorState& ChromeCompositorStateMachine_MinorState::operator=(ChromeCompositorStateMachine_MinorState&&) = default;
24492 
operator ==(const ChromeCompositorStateMachine_MinorState & other) const24493 bool ChromeCompositorStateMachine_MinorState::operator==(const ChromeCompositorStateMachine_MinorState& other) const {
24494   return unknown_fields_ == other.unknown_fields_
24495    && commit_count_ == other.commit_count_
24496    && current_frame_number_ == other.current_frame_number_
24497    && last_frame_number_submit_performed_ == other.last_frame_number_submit_performed_
24498    && last_frame_number_draw_performed_ == other.last_frame_number_draw_performed_
24499    && last_frame_number_begin_main_frame_sent_ == other.last_frame_number_begin_main_frame_sent_
24500    && did_draw_ == other.did_draw_
24501    && did_send_begin_main_frame_for_current_frame_ == other.did_send_begin_main_frame_for_current_frame_
24502    && did_notify_begin_main_frame_not_expected_until_ == other.did_notify_begin_main_frame_not_expected_until_
24503    && did_notify_begin_main_frame_not_expected_soon_ == other.did_notify_begin_main_frame_not_expected_soon_
24504    && wants_begin_main_frame_not_expected_ == other.wants_begin_main_frame_not_expected_
24505    && did_commit_during_frame_ == other.did_commit_during_frame_
24506    && did_invalidate_layer_tree_frame_sink_ == other.did_invalidate_layer_tree_frame_sink_
24507    && did_perform_impl_side_invalidaion_ == other.did_perform_impl_side_invalidaion_
24508    && did_prepare_tiles_ == other.did_prepare_tiles_
24509    && consecutive_checkerboard_animations_ == other.consecutive_checkerboard_animations_
24510    && pending_submit_frames_ == other.pending_submit_frames_
24511    && submit_frames_with_current_layer_tree_frame_sink_ == other.submit_frames_with_current_layer_tree_frame_sink_
24512    && needs_redraw_ == other.needs_redraw_
24513    && needs_prepare_tiles_ == other.needs_prepare_tiles_
24514    && needs_begin_main_frame_ == other.needs_begin_main_frame_
24515    && needs_one_begin_impl_frame_ == other.needs_one_begin_impl_frame_
24516    && visible_ == other.visible_
24517    && begin_frame_source_paused_ == other.begin_frame_source_paused_
24518    && can_draw_ == other.can_draw_
24519    && resourceless_draw_ == other.resourceless_draw_
24520    && has_pending_tree_ == other.has_pending_tree_
24521    && pending_tree_is_ready_for_activation_ == other.pending_tree_is_ready_for_activation_
24522    && active_tree_needs_first_draw_ == other.active_tree_needs_first_draw_
24523    && active_tree_is_ready_to_draw_ == other.active_tree_is_ready_to_draw_
24524    && did_create_and_initialize_first_layer_tree_frame_sink_ == other.did_create_and_initialize_first_layer_tree_frame_sink_
24525    && tree_priority_ == other.tree_priority_
24526    && scroll_handler_state_ == other.scroll_handler_state_
24527    && critical_begin_main_frame_to_activate_is_fast_ == other.critical_begin_main_frame_to_activate_is_fast_
24528    && main_thread_missed_last_deadline_ == other.main_thread_missed_last_deadline_
24529    && skip_next_begin_main_frame_to_reduce_latency_ == other.skip_next_begin_main_frame_to_reduce_latency_
24530    && video_needs_begin_frames_ == other.video_needs_begin_frames_
24531    && defer_begin_main_frame_ == other.defer_begin_main_frame_
24532    && last_commit_had_no_updates_ == other.last_commit_had_no_updates_
24533    && did_draw_in_last_frame_ == other.did_draw_in_last_frame_
24534    && did_submit_in_last_frame_ == other.did_submit_in_last_frame_
24535    && needs_impl_side_invalidation_ == other.needs_impl_side_invalidation_
24536    && current_pending_tree_is_impl_side_ == other.current_pending_tree_is_impl_side_
24537    && previous_pending_tree_was_impl_side_ == other.previous_pending_tree_was_impl_side_
24538    && processing_animation_worklets_for_active_tree_ == other.processing_animation_worklets_for_active_tree_
24539    && processing_animation_worklets_for_pending_tree_ == other.processing_animation_worklets_for_pending_tree_
24540    && processing_paint_worklets_for_pending_tree_ == other.processing_paint_worklets_for_pending_tree_;
24541 }
24542 
ParseFromArray(const void * raw,size_t size)24543 bool ChromeCompositorStateMachine_MinorState::ParseFromArray(const void* raw, size_t size) {
24544   unknown_fields_.clear();
24545   bool packed_error = false;
24546 
24547   ::protozero::ProtoDecoder dec(raw, size);
24548   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
24549     if (field.id() < _has_field_.size()) {
24550       _has_field_.set(field.id());
24551     }
24552     switch (field.id()) {
24553       case 1 /* commit_count */:
24554         field.get(&commit_count_);
24555         break;
24556       case 2 /* current_frame_number */:
24557         field.get(&current_frame_number_);
24558         break;
24559       case 3 /* last_frame_number_submit_performed */:
24560         field.get(&last_frame_number_submit_performed_);
24561         break;
24562       case 4 /* last_frame_number_draw_performed */:
24563         field.get(&last_frame_number_draw_performed_);
24564         break;
24565       case 5 /* last_frame_number_begin_main_frame_sent */:
24566         field.get(&last_frame_number_begin_main_frame_sent_);
24567         break;
24568       case 6 /* did_draw */:
24569         field.get(&did_draw_);
24570         break;
24571       case 7 /* did_send_begin_main_frame_for_current_frame */:
24572         field.get(&did_send_begin_main_frame_for_current_frame_);
24573         break;
24574       case 8 /* did_notify_begin_main_frame_not_expected_until */:
24575         field.get(&did_notify_begin_main_frame_not_expected_until_);
24576         break;
24577       case 9 /* did_notify_begin_main_frame_not_expected_soon */:
24578         field.get(&did_notify_begin_main_frame_not_expected_soon_);
24579         break;
24580       case 10 /* wants_begin_main_frame_not_expected */:
24581         field.get(&wants_begin_main_frame_not_expected_);
24582         break;
24583       case 11 /* did_commit_during_frame */:
24584         field.get(&did_commit_during_frame_);
24585         break;
24586       case 12 /* did_invalidate_layer_tree_frame_sink */:
24587         field.get(&did_invalidate_layer_tree_frame_sink_);
24588         break;
24589       case 13 /* did_perform_impl_side_invalidaion */:
24590         field.get(&did_perform_impl_side_invalidaion_);
24591         break;
24592       case 14 /* did_prepare_tiles */:
24593         field.get(&did_prepare_tiles_);
24594         break;
24595       case 15 /* consecutive_checkerboard_animations */:
24596         field.get(&consecutive_checkerboard_animations_);
24597         break;
24598       case 16 /* pending_submit_frames */:
24599         field.get(&pending_submit_frames_);
24600         break;
24601       case 17 /* submit_frames_with_current_layer_tree_frame_sink */:
24602         field.get(&submit_frames_with_current_layer_tree_frame_sink_);
24603         break;
24604       case 18 /* needs_redraw */:
24605         field.get(&needs_redraw_);
24606         break;
24607       case 19 /* needs_prepare_tiles */:
24608         field.get(&needs_prepare_tiles_);
24609         break;
24610       case 20 /* needs_begin_main_frame */:
24611         field.get(&needs_begin_main_frame_);
24612         break;
24613       case 21 /* needs_one_begin_impl_frame */:
24614         field.get(&needs_one_begin_impl_frame_);
24615         break;
24616       case 22 /* visible */:
24617         field.get(&visible_);
24618         break;
24619       case 23 /* begin_frame_source_paused */:
24620         field.get(&begin_frame_source_paused_);
24621         break;
24622       case 24 /* can_draw */:
24623         field.get(&can_draw_);
24624         break;
24625       case 25 /* resourceless_draw */:
24626         field.get(&resourceless_draw_);
24627         break;
24628       case 26 /* has_pending_tree */:
24629         field.get(&has_pending_tree_);
24630         break;
24631       case 27 /* pending_tree_is_ready_for_activation */:
24632         field.get(&pending_tree_is_ready_for_activation_);
24633         break;
24634       case 28 /* active_tree_needs_first_draw */:
24635         field.get(&active_tree_needs_first_draw_);
24636         break;
24637       case 29 /* active_tree_is_ready_to_draw */:
24638         field.get(&active_tree_is_ready_to_draw_);
24639         break;
24640       case 30 /* did_create_and_initialize_first_layer_tree_frame_sink */:
24641         field.get(&did_create_and_initialize_first_layer_tree_frame_sink_);
24642         break;
24643       case 31 /* tree_priority */:
24644         field.get(&tree_priority_);
24645         break;
24646       case 32 /* scroll_handler_state */:
24647         field.get(&scroll_handler_state_);
24648         break;
24649       case 33 /* critical_begin_main_frame_to_activate_is_fast */:
24650         field.get(&critical_begin_main_frame_to_activate_is_fast_);
24651         break;
24652       case 34 /* main_thread_missed_last_deadline */:
24653         field.get(&main_thread_missed_last_deadline_);
24654         break;
24655       case 35 /* skip_next_begin_main_frame_to_reduce_latency */:
24656         field.get(&skip_next_begin_main_frame_to_reduce_latency_);
24657         break;
24658       case 36 /* video_needs_begin_frames */:
24659         field.get(&video_needs_begin_frames_);
24660         break;
24661       case 37 /* defer_begin_main_frame */:
24662         field.get(&defer_begin_main_frame_);
24663         break;
24664       case 38 /* last_commit_had_no_updates */:
24665         field.get(&last_commit_had_no_updates_);
24666         break;
24667       case 39 /* did_draw_in_last_frame */:
24668         field.get(&did_draw_in_last_frame_);
24669         break;
24670       case 40 /* did_submit_in_last_frame */:
24671         field.get(&did_submit_in_last_frame_);
24672         break;
24673       case 41 /* needs_impl_side_invalidation */:
24674         field.get(&needs_impl_side_invalidation_);
24675         break;
24676       case 42 /* current_pending_tree_is_impl_side */:
24677         field.get(&current_pending_tree_is_impl_side_);
24678         break;
24679       case 43 /* previous_pending_tree_was_impl_side */:
24680         field.get(&previous_pending_tree_was_impl_side_);
24681         break;
24682       case 44 /* processing_animation_worklets_for_active_tree */:
24683         field.get(&processing_animation_worklets_for_active_tree_);
24684         break;
24685       case 45 /* processing_animation_worklets_for_pending_tree */:
24686         field.get(&processing_animation_worklets_for_pending_tree_);
24687         break;
24688       case 46 /* processing_paint_worklets_for_pending_tree */:
24689         field.get(&processing_paint_worklets_for_pending_tree_);
24690         break;
24691       default:
24692         field.SerializeAndAppendTo(&unknown_fields_);
24693         break;
24694     }
24695   }
24696   return !packed_error && !dec.bytes_left();
24697 }
24698 
SerializeAsString() const24699 std::string ChromeCompositorStateMachine_MinorState::SerializeAsString() const {
24700   ::protozero::HeapBuffered<::protozero::Message> msg;
24701   Serialize(msg.get());
24702   return msg.SerializeAsString();
24703 }
24704 
SerializeAsArray() const24705 std::vector<uint8_t> ChromeCompositorStateMachine_MinorState::SerializeAsArray() const {
24706   ::protozero::HeapBuffered<::protozero::Message> msg;
24707   Serialize(msg.get());
24708   return msg.SerializeAsArray();
24709 }
24710 
Serialize(::protozero::Message * msg) const24711 void ChromeCompositorStateMachine_MinorState::Serialize(::protozero::Message* msg) const {
24712   // Field 1: commit_count
24713   if (_has_field_[1]) {
24714     msg->AppendVarInt(1, commit_count_);
24715   }
24716 
24717   // Field 2: current_frame_number
24718   if (_has_field_[2]) {
24719     msg->AppendVarInt(2, current_frame_number_);
24720   }
24721 
24722   // Field 3: last_frame_number_submit_performed
24723   if (_has_field_[3]) {
24724     msg->AppendVarInt(3, last_frame_number_submit_performed_);
24725   }
24726 
24727   // Field 4: last_frame_number_draw_performed
24728   if (_has_field_[4]) {
24729     msg->AppendVarInt(4, last_frame_number_draw_performed_);
24730   }
24731 
24732   // Field 5: last_frame_number_begin_main_frame_sent
24733   if (_has_field_[5]) {
24734     msg->AppendVarInt(5, last_frame_number_begin_main_frame_sent_);
24735   }
24736 
24737   // Field 6: did_draw
24738   if (_has_field_[6]) {
24739     msg->AppendTinyVarInt(6, did_draw_);
24740   }
24741 
24742   // Field 7: did_send_begin_main_frame_for_current_frame
24743   if (_has_field_[7]) {
24744     msg->AppendTinyVarInt(7, did_send_begin_main_frame_for_current_frame_);
24745   }
24746 
24747   // Field 8: did_notify_begin_main_frame_not_expected_until
24748   if (_has_field_[8]) {
24749     msg->AppendTinyVarInt(8, did_notify_begin_main_frame_not_expected_until_);
24750   }
24751 
24752   // Field 9: did_notify_begin_main_frame_not_expected_soon
24753   if (_has_field_[9]) {
24754     msg->AppendTinyVarInt(9, did_notify_begin_main_frame_not_expected_soon_);
24755   }
24756 
24757   // Field 10: wants_begin_main_frame_not_expected
24758   if (_has_field_[10]) {
24759     msg->AppendTinyVarInt(10, wants_begin_main_frame_not_expected_);
24760   }
24761 
24762   // Field 11: did_commit_during_frame
24763   if (_has_field_[11]) {
24764     msg->AppendTinyVarInt(11, did_commit_during_frame_);
24765   }
24766 
24767   // Field 12: did_invalidate_layer_tree_frame_sink
24768   if (_has_field_[12]) {
24769     msg->AppendTinyVarInt(12, did_invalidate_layer_tree_frame_sink_);
24770   }
24771 
24772   // Field 13: did_perform_impl_side_invalidaion
24773   if (_has_field_[13]) {
24774     msg->AppendTinyVarInt(13, did_perform_impl_side_invalidaion_);
24775   }
24776 
24777   // Field 14: did_prepare_tiles
24778   if (_has_field_[14]) {
24779     msg->AppendTinyVarInt(14, did_prepare_tiles_);
24780   }
24781 
24782   // Field 15: consecutive_checkerboard_animations
24783   if (_has_field_[15]) {
24784     msg->AppendVarInt(15, consecutive_checkerboard_animations_);
24785   }
24786 
24787   // Field 16: pending_submit_frames
24788   if (_has_field_[16]) {
24789     msg->AppendVarInt(16, pending_submit_frames_);
24790   }
24791 
24792   // Field 17: submit_frames_with_current_layer_tree_frame_sink
24793   if (_has_field_[17]) {
24794     msg->AppendVarInt(17, submit_frames_with_current_layer_tree_frame_sink_);
24795   }
24796 
24797   // Field 18: needs_redraw
24798   if (_has_field_[18]) {
24799     msg->AppendTinyVarInt(18, needs_redraw_);
24800   }
24801 
24802   // Field 19: needs_prepare_tiles
24803   if (_has_field_[19]) {
24804     msg->AppendTinyVarInt(19, needs_prepare_tiles_);
24805   }
24806 
24807   // Field 20: needs_begin_main_frame
24808   if (_has_field_[20]) {
24809     msg->AppendTinyVarInt(20, needs_begin_main_frame_);
24810   }
24811 
24812   // Field 21: needs_one_begin_impl_frame
24813   if (_has_field_[21]) {
24814     msg->AppendTinyVarInt(21, needs_one_begin_impl_frame_);
24815   }
24816 
24817   // Field 22: visible
24818   if (_has_field_[22]) {
24819     msg->AppendTinyVarInt(22, visible_);
24820   }
24821 
24822   // Field 23: begin_frame_source_paused
24823   if (_has_field_[23]) {
24824     msg->AppendTinyVarInt(23, begin_frame_source_paused_);
24825   }
24826 
24827   // Field 24: can_draw
24828   if (_has_field_[24]) {
24829     msg->AppendTinyVarInt(24, can_draw_);
24830   }
24831 
24832   // Field 25: resourceless_draw
24833   if (_has_field_[25]) {
24834     msg->AppendTinyVarInt(25, resourceless_draw_);
24835   }
24836 
24837   // Field 26: has_pending_tree
24838   if (_has_field_[26]) {
24839     msg->AppendTinyVarInt(26, has_pending_tree_);
24840   }
24841 
24842   // Field 27: pending_tree_is_ready_for_activation
24843   if (_has_field_[27]) {
24844     msg->AppendTinyVarInt(27, pending_tree_is_ready_for_activation_);
24845   }
24846 
24847   // Field 28: active_tree_needs_first_draw
24848   if (_has_field_[28]) {
24849     msg->AppendTinyVarInt(28, active_tree_needs_first_draw_);
24850   }
24851 
24852   // Field 29: active_tree_is_ready_to_draw
24853   if (_has_field_[29]) {
24854     msg->AppendTinyVarInt(29, active_tree_is_ready_to_draw_);
24855   }
24856 
24857   // Field 30: did_create_and_initialize_first_layer_tree_frame_sink
24858   if (_has_field_[30]) {
24859     msg->AppendTinyVarInt(30, did_create_and_initialize_first_layer_tree_frame_sink_);
24860   }
24861 
24862   // Field 31: tree_priority
24863   if (_has_field_[31]) {
24864     msg->AppendVarInt(31, tree_priority_);
24865   }
24866 
24867   // Field 32: scroll_handler_state
24868   if (_has_field_[32]) {
24869     msg->AppendVarInt(32, scroll_handler_state_);
24870   }
24871 
24872   // Field 33: critical_begin_main_frame_to_activate_is_fast
24873   if (_has_field_[33]) {
24874     msg->AppendTinyVarInt(33, critical_begin_main_frame_to_activate_is_fast_);
24875   }
24876 
24877   // Field 34: main_thread_missed_last_deadline
24878   if (_has_field_[34]) {
24879     msg->AppendTinyVarInt(34, main_thread_missed_last_deadline_);
24880   }
24881 
24882   // Field 35: skip_next_begin_main_frame_to_reduce_latency
24883   if (_has_field_[35]) {
24884     msg->AppendTinyVarInt(35, skip_next_begin_main_frame_to_reduce_latency_);
24885   }
24886 
24887   // Field 36: video_needs_begin_frames
24888   if (_has_field_[36]) {
24889     msg->AppendTinyVarInt(36, video_needs_begin_frames_);
24890   }
24891 
24892   // Field 37: defer_begin_main_frame
24893   if (_has_field_[37]) {
24894     msg->AppendTinyVarInt(37, defer_begin_main_frame_);
24895   }
24896 
24897   // Field 38: last_commit_had_no_updates
24898   if (_has_field_[38]) {
24899     msg->AppendTinyVarInt(38, last_commit_had_no_updates_);
24900   }
24901 
24902   // Field 39: did_draw_in_last_frame
24903   if (_has_field_[39]) {
24904     msg->AppendTinyVarInt(39, did_draw_in_last_frame_);
24905   }
24906 
24907   // Field 40: did_submit_in_last_frame
24908   if (_has_field_[40]) {
24909     msg->AppendTinyVarInt(40, did_submit_in_last_frame_);
24910   }
24911 
24912   // Field 41: needs_impl_side_invalidation
24913   if (_has_field_[41]) {
24914     msg->AppendTinyVarInt(41, needs_impl_side_invalidation_);
24915   }
24916 
24917   // Field 42: current_pending_tree_is_impl_side
24918   if (_has_field_[42]) {
24919     msg->AppendTinyVarInt(42, current_pending_tree_is_impl_side_);
24920   }
24921 
24922   // Field 43: previous_pending_tree_was_impl_side
24923   if (_has_field_[43]) {
24924     msg->AppendTinyVarInt(43, previous_pending_tree_was_impl_side_);
24925   }
24926 
24927   // Field 44: processing_animation_worklets_for_active_tree
24928   if (_has_field_[44]) {
24929     msg->AppendTinyVarInt(44, processing_animation_worklets_for_active_tree_);
24930   }
24931 
24932   // Field 45: processing_animation_worklets_for_pending_tree
24933   if (_has_field_[45]) {
24934     msg->AppendTinyVarInt(45, processing_animation_worklets_for_pending_tree_);
24935   }
24936 
24937   // Field 46: processing_paint_worklets_for_pending_tree
24938   if (_has_field_[46]) {
24939     msg->AppendTinyVarInt(46, processing_paint_worklets_for_pending_tree_);
24940   }
24941 
24942   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
24943 }
24944 
24945 
24946 ChromeCompositorStateMachine_MajorState::ChromeCompositorStateMachine_MajorState() = default;
24947 ChromeCompositorStateMachine_MajorState::~ChromeCompositorStateMachine_MajorState() = default;
24948 ChromeCompositorStateMachine_MajorState::ChromeCompositorStateMachine_MajorState(const ChromeCompositorStateMachine_MajorState&) = default;
24949 ChromeCompositorStateMachine_MajorState& ChromeCompositorStateMachine_MajorState::operator=(const ChromeCompositorStateMachine_MajorState&) = default;
24950 ChromeCompositorStateMachine_MajorState::ChromeCompositorStateMachine_MajorState(ChromeCompositorStateMachine_MajorState&&) noexcept = default;
24951 ChromeCompositorStateMachine_MajorState& ChromeCompositorStateMachine_MajorState::operator=(ChromeCompositorStateMachine_MajorState&&) = default;
24952 
operator ==(const ChromeCompositorStateMachine_MajorState & other) const24953 bool ChromeCompositorStateMachine_MajorState::operator==(const ChromeCompositorStateMachine_MajorState& other) const {
24954   return unknown_fields_ == other.unknown_fields_
24955    && next_action_ == other.next_action_
24956    && begin_impl_frame_state_ == other.begin_impl_frame_state_
24957    && begin_main_frame_state_ == other.begin_main_frame_state_
24958    && layer_tree_frame_sink_state_ == other.layer_tree_frame_sink_state_
24959    && forced_redraw_state_ == other.forced_redraw_state_;
24960 }
24961 
ParseFromArray(const void * raw,size_t size)24962 bool ChromeCompositorStateMachine_MajorState::ParseFromArray(const void* raw, size_t size) {
24963   unknown_fields_.clear();
24964   bool packed_error = false;
24965 
24966   ::protozero::ProtoDecoder dec(raw, size);
24967   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
24968     if (field.id() < _has_field_.size()) {
24969       _has_field_.set(field.id());
24970     }
24971     switch (field.id()) {
24972       case 1 /* next_action */:
24973         field.get(&next_action_);
24974         break;
24975       case 2 /* begin_impl_frame_state */:
24976         field.get(&begin_impl_frame_state_);
24977         break;
24978       case 3 /* begin_main_frame_state */:
24979         field.get(&begin_main_frame_state_);
24980         break;
24981       case 4 /* layer_tree_frame_sink_state */:
24982         field.get(&layer_tree_frame_sink_state_);
24983         break;
24984       case 5 /* forced_redraw_state */:
24985         field.get(&forced_redraw_state_);
24986         break;
24987       default:
24988         field.SerializeAndAppendTo(&unknown_fields_);
24989         break;
24990     }
24991   }
24992   return !packed_error && !dec.bytes_left();
24993 }
24994 
SerializeAsString() const24995 std::string ChromeCompositorStateMachine_MajorState::SerializeAsString() const {
24996   ::protozero::HeapBuffered<::protozero::Message> msg;
24997   Serialize(msg.get());
24998   return msg.SerializeAsString();
24999 }
25000 
SerializeAsArray() const25001 std::vector<uint8_t> ChromeCompositorStateMachine_MajorState::SerializeAsArray() const {
25002   ::protozero::HeapBuffered<::protozero::Message> msg;
25003   Serialize(msg.get());
25004   return msg.SerializeAsArray();
25005 }
25006 
Serialize(::protozero::Message * msg) const25007 void ChromeCompositorStateMachine_MajorState::Serialize(::protozero::Message* msg) const {
25008   // Field 1: next_action
25009   if (_has_field_[1]) {
25010     msg->AppendVarInt(1, next_action_);
25011   }
25012 
25013   // Field 2: begin_impl_frame_state
25014   if (_has_field_[2]) {
25015     msg->AppendVarInt(2, begin_impl_frame_state_);
25016   }
25017 
25018   // Field 3: begin_main_frame_state
25019   if (_has_field_[3]) {
25020     msg->AppendVarInt(3, begin_main_frame_state_);
25021   }
25022 
25023   // Field 4: layer_tree_frame_sink_state
25024   if (_has_field_[4]) {
25025     msg->AppendVarInt(4, layer_tree_frame_sink_state_);
25026   }
25027 
25028   // Field 5: forced_redraw_state
25029   if (_has_field_[5]) {
25030     msg->AppendVarInt(5, forced_redraw_state_);
25031   }
25032 
25033   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
25034 }
25035 
25036 
25037 ChromeCompositorSchedulerState::ChromeCompositorSchedulerState() = default;
25038 ChromeCompositorSchedulerState::~ChromeCompositorSchedulerState() = default;
25039 ChromeCompositorSchedulerState::ChromeCompositorSchedulerState(const ChromeCompositorSchedulerState&) = default;
25040 ChromeCompositorSchedulerState& ChromeCompositorSchedulerState::operator=(const ChromeCompositorSchedulerState&) = default;
25041 ChromeCompositorSchedulerState::ChromeCompositorSchedulerState(ChromeCompositorSchedulerState&&) noexcept = default;
25042 ChromeCompositorSchedulerState& ChromeCompositorSchedulerState::operator=(ChromeCompositorSchedulerState&&) = default;
25043 
operator ==(const ChromeCompositorSchedulerState & other) const25044 bool ChromeCompositorSchedulerState::operator==(const ChromeCompositorSchedulerState& other) const {
25045   return unknown_fields_ == other.unknown_fields_
25046    && state_machine_ == other.state_machine_
25047    && observing_begin_frame_source_ == other.observing_begin_frame_source_
25048    && begin_impl_frame_deadline_task_ == other.begin_impl_frame_deadline_task_
25049    && pending_begin_frame_task_ == other.pending_begin_frame_task_
25050    && skipped_last_frame_missed_exceeded_deadline_ == other.skipped_last_frame_missed_exceeded_deadline_
25051    && skipped_last_frame_to_reduce_latency_ == other.skipped_last_frame_to_reduce_latency_
25052    && inside_action_ == other.inside_action_
25053    && deadline_mode_ == other.deadline_mode_
25054    && deadline_us_ == other.deadline_us_
25055    && deadline_scheduled_at_us_ == other.deadline_scheduled_at_us_
25056    && now_us_ == other.now_us_
25057    && now_to_deadline_delta_us_ == other.now_to_deadline_delta_us_
25058    && now_to_deadline_scheduled_at_delta_us_ == other.now_to_deadline_scheduled_at_delta_us_
25059    && begin_impl_frame_args_ == other.begin_impl_frame_args_
25060    && begin_frame_observer_state_ == other.begin_frame_observer_state_
25061    && begin_frame_source_state_ == other.begin_frame_source_state_
25062    && compositor_timing_history_ == other.compositor_timing_history_;
25063 }
25064 
ParseFromArray(const void * raw,size_t size)25065 bool ChromeCompositorSchedulerState::ParseFromArray(const void* raw, size_t size) {
25066   unknown_fields_.clear();
25067   bool packed_error = false;
25068 
25069   ::protozero::ProtoDecoder dec(raw, size);
25070   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
25071     if (field.id() < _has_field_.size()) {
25072       _has_field_.set(field.id());
25073     }
25074     switch (field.id()) {
25075       case 1 /* state_machine */:
25076         (*state_machine_).ParseFromArray(field.data(), field.size());
25077         break;
25078       case 2 /* observing_begin_frame_source */:
25079         field.get(&observing_begin_frame_source_);
25080         break;
25081       case 3 /* begin_impl_frame_deadline_task */:
25082         field.get(&begin_impl_frame_deadline_task_);
25083         break;
25084       case 4 /* pending_begin_frame_task */:
25085         field.get(&pending_begin_frame_task_);
25086         break;
25087       case 5 /* skipped_last_frame_missed_exceeded_deadline */:
25088         field.get(&skipped_last_frame_missed_exceeded_deadline_);
25089         break;
25090       case 6 /* skipped_last_frame_to_reduce_latency */:
25091         field.get(&skipped_last_frame_to_reduce_latency_);
25092         break;
25093       case 7 /* inside_action */:
25094         field.get(&inside_action_);
25095         break;
25096       case 8 /* deadline_mode */:
25097         field.get(&deadline_mode_);
25098         break;
25099       case 9 /* deadline_us */:
25100         field.get(&deadline_us_);
25101         break;
25102       case 10 /* deadline_scheduled_at_us */:
25103         field.get(&deadline_scheduled_at_us_);
25104         break;
25105       case 11 /* now_us */:
25106         field.get(&now_us_);
25107         break;
25108       case 12 /* now_to_deadline_delta_us */:
25109         field.get(&now_to_deadline_delta_us_);
25110         break;
25111       case 13 /* now_to_deadline_scheduled_at_delta_us */:
25112         field.get(&now_to_deadline_scheduled_at_delta_us_);
25113         break;
25114       case 14 /* begin_impl_frame_args */:
25115         (*begin_impl_frame_args_).ParseFromArray(field.data(), field.size());
25116         break;
25117       case 15 /* begin_frame_observer_state */:
25118         (*begin_frame_observer_state_).ParseFromArray(field.data(), field.size());
25119         break;
25120       case 16 /* begin_frame_source_state */:
25121         (*begin_frame_source_state_).ParseFromArray(field.data(), field.size());
25122         break;
25123       case 17 /* compositor_timing_history */:
25124         (*compositor_timing_history_).ParseFromArray(field.data(), field.size());
25125         break;
25126       default:
25127         field.SerializeAndAppendTo(&unknown_fields_);
25128         break;
25129     }
25130   }
25131   return !packed_error && !dec.bytes_left();
25132 }
25133 
SerializeAsString() const25134 std::string ChromeCompositorSchedulerState::SerializeAsString() const {
25135   ::protozero::HeapBuffered<::protozero::Message> msg;
25136   Serialize(msg.get());
25137   return msg.SerializeAsString();
25138 }
25139 
SerializeAsArray() const25140 std::vector<uint8_t> ChromeCompositorSchedulerState::SerializeAsArray() const {
25141   ::protozero::HeapBuffered<::protozero::Message> msg;
25142   Serialize(msg.get());
25143   return msg.SerializeAsArray();
25144 }
25145 
Serialize(::protozero::Message * msg) const25146 void ChromeCompositorSchedulerState::Serialize(::protozero::Message* msg) const {
25147   // Field 1: state_machine
25148   if (_has_field_[1]) {
25149     (*state_machine_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
25150   }
25151 
25152   // Field 2: observing_begin_frame_source
25153   if (_has_field_[2]) {
25154     msg->AppendTinyVarInt(2, observing_begin_frame_source_);
25155   }
25156 
25157   // Field 3: begin_impl_frame_deadline_task
25158   if (_has_field_[3]) {
25159     msg->AppendTinyVarInt(3, begin_impl_frame_deadline_task_);
25160   }
25161 
25162   // Field 4: pending_begin_frame_task
25163   if (_has_field_[4]) {
25164     msg->AppendTinyVarInt(4, pending_begin_frame_task_);
25165   }
25166 
25167   // Field 5: skipped_last_frame_missed_exceeded_deadline
25168   if (_has_field_[5]) {
25169     msg->AppendTinyVarInt(5, skipped_last_frame_missed_exceeded_deadline_);
25170   }
25171 
25172   // Field 6: skipped_last_frame_to_reduce_latency
25173   if (_has_field_[6]) {
25174     msg->AppendTinyVarInt(6, skipped_last_frame_to_reduce_latency_);
25175   }
25176 
25177   // Field 7: inside_action
25178   if (_has_field_[7]) {
25179     msg->AppendVarInt(7, inside_action_);
25180   }
25181 
25182   // Field 8: deadline_mode
25183   if (_has_field_[8]) {
25184     msg->AppendVarInt(8, deadline_mode_);
25185   }
25186 
25187   // Field 9: deadline_us
25188   if (_has_field_[9]) {
25189     msg->AppendVarInt(9, deadline_us_);
25190   }
25191 
25192   // Field 10: deadline_scheduled_at_us
25193   if (_has_field_[10]) {
25194     msg->AppendVarInt(10, deadline_scheduled_at_us_);
25195   }
25196 
25197   // Field 11: now_us
25198   if (_has_field_[11]) {
25199     msg->AppendVarInt(11, now_us_);
25200   }
25201 
25202   // Field 12: now_to_deadline_delta_us
25203   if (_has_field_[12]) {
25204     msg->AppendVarInt(12, now_to_deadline_delta_us_);
25205   }
25206 
25207   // Field 13: now_to_deadline_scheduled_at_delta_us
25208   if (_has_field_[13]) {
25209     msg->AppendVarInt(13, now_to_deadline_scheduled_at_delta_us_);
25210   }
25211 
25212   // Field 14: begin_impl_frame_args
25213   if (_has_field_[14]) {
25214     (*begin_impl_frame_args_).Serialize(msg->BeginNestedMessage<::protozero::Message>(14));
25215   }
25216 
25217   // Field 15: begin_frame_observer_state
25218   if (_has_field_[15]) {
25219     (*begin_frame_observer_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(15));
25220   }
25221 
25222   // Field 16: begin_frame_source_state
25223   if (_has_field_[16]) {
25224     (*begin_frame_source_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(16));
25225   }
25226 
25227   // Field 17: compositor_timing_history
25228   if (_has_field_[17]) {
25229     (*compositor_timing_history_).Serialize(msg->BeginNestedMessage<::protozero::Message>(17));
25230   }
25231 
25232   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
25233 }
25234 
25235 }  // namespace perfetto
25236 }  // namespace protos
25237 }  // namespace gen
25238 #if defined(__GNUC__) || defined(__clang__)
25239 #pragma GCC diagnostic pop
25240 #endif
25241 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_content_settings_event_info.gen.cc
25242 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_content_settings_event_info.gen.h
25243 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
25244 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_CONTENT_SETTINGS_EVENT_INFO_PROTO_CPP_H_
25245 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_CONTENT_SETTINGS_EVENT_INFO_PROTO_CPP_H_
25246 
25247 #include <stdint.h>
25248 #include <bitset>
25249 #include <vector>
25250 #include <string>
25251 #include <type_traits>
25252 
25253 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
25254 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
25255 // gen_amalgamated expanded: #include "perfetto/base/export.h"
25256 
25257 namespace perfetto {
25258 namespace protos {
25259 namespace gen {
25260 class ChromeContentSettingsEventInfo;
25261 }  // namespace perfetto
25262 }  // namespace protos
25263 }  // namespace gen
25264 
25265 namespace protozero {
25266 class Message;
25267 }  // namespace protozero
25268 
25269 namespace perfetto {
25270 namespace protos {
25271 namespace gen {
25272 
25273 class PERFETTO_EXPORT ChromeContentSettingsEventInfo : public ::protozero::CppMessageObj {
25274  public:
25275   enum FieldNumbers {
25276     kNumberOfExceptionsFieldNumber = 1,
25277   };
25278 
25279   ChromeContentSettingsEventInfo();
25280   ~ChromeContentSettingsEventInfo() override;
25281   ChromeContentSettingsEventInfo(ChromeContentSettingsEventInfo&&) noexcept;
25282   ChromeContentSettingsEventInfo& operator=(ChromeContentSettingsEventInfo&&);
25283   ChromeContentSettingsEventInfo(const ChromeContentSettingsEventInfo&);
25284   ChromeContentSettingsEventInfo& operator=(const ChromeContentSettingsEventInfo&);
25285   bool operator==(const ChromeContentSettingsEventInfo&) const;
operator !=(const ChromeContentSettingsEventInfo & other) const25286   bool operator!=(const ChromeContentSettingsEventInfo& other) const { return !(*this == other); }
25287 
25288   bool ParseFromArray(const void*, size_t) override;
25289   std::string SerializeAsString() const override;
25290   std::vector<uint8_t> SerializeAsArray() const override;
25291   void Serialize(::protozero::Message*) const;
25292 
has_number_of_exceptions() const25293   bool has_number_of_exceptions() const { return _has_field_[1]; }
number_of_exceptions() const25294   uint32_t number_of_exceptions() const { return number_of_exceptions_; }
set_number_of_exceptions(uint32_t value)25295   void set_number_of_exceptions(uint32_t value) { number_of_exceptions_ = value; _has_field_.set(1); }
25296 
25297  private:
25298   uint32_t number_of_exceptions_{};
25299 
25300   // Allows to preserve unknown protobuf fields for compatibility
25301   // with future versions of .proto files.
25302   std::string unknown_fields_;
25303 
25304   std::bitset<2> _has_field_{};
25305 };
25306 
25307 }  // namespace perfetto
25308 }  // namespace protos
25309 }  // namespace gen
25310 
25311 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_CONTENT_SETTINGS_EVENT_INFO_PROTO_CPP_H_
25312 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
25313 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
25314 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
25315 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
25316 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
25317 #if defined(__GNUC__) || defined(__clang__)
25318 #pragma GCC diagnostic push
25319 #pragma GCC diagnostic ignored "-Wfloat-equal"
25320 #endif
25321 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_content_settings_event_info.gen.h"
25322 
25323 namespace perfetto {
25324 namespace protos {
25325 namespace gen {
25326 
25327 ChromeContentSettingsEventInfo::ChromeContentSettingsEventInfo() = default;
25328 ChromeContentSettingsEventInfo::~ChromeContentSettingsEventInfo() = default;
25329 ChromeContentSettingsEventInfo::ChromeContentSettingsEventInfo(const ChromeContentSettingsEventInfo&) = default;
25330 ChromeContentSettingsEventInfo& ChromeContentSettingsEventInfo::operator=(const ChromeContentSettingsEventInfo&) = default;
25331 ChromeContentSettingsEventInfo::ChromeContentSettingsEventInfo(ChromeContentSettingsEventInfo&&) noexcept = default;
25332 ChromeContentSettingsEventInfo& ChromeContentSettingsEventInfo::operator=(ChromeContentSettingsEventInfo&&) = default;
25333 
operator ==(const ChromeContentSettingsEventInfo & other) const25334 bool ChromeContentSettingsEventInfo::operator==(const ChromeContentSettingsEventInfo& other) const {
25335   return unknown_fields_ == other.unknown_fields_
25336    && number_of_exceptions_ == other.number_of_exceptions_;
25337 }
25338 
ParseFromArray(const void * raw,size_t size)25339 bool ChromeContentSettingsEventInfo::ParseFromArray(const void* raw, size_t size) {
25340   unknown_fields_.clear();
25341   bool packed_error = false;
25342 
25343   ::protozero::ProtoDecoder dec(raw, size);
25344   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
25345     if (field.id() < _has_field_.size()) {
25346       _has_field_.set(field.id());
25347     }
25348     switch (field.id()) {
25349       case 1 /* number_of_exceptions */:
25350         field.get(&number_of_exceptions_);
25351         break;
25352       default:
25353         field.SerializeAndAppendTo(&unknown_fields_);
25354         break;
25355     }
25356   }
25357   return !packed_error && !dec.bytes_left();
25358 }
25359 
SerializeAsString() const25360 std::string ChromeContentSettingsEventInfo::SerializeAsString() const {
25361   ::protozero::HeapBuffered<::protozero::Message> msg;
25362   Serialize(msg.get());
25363   return msg.SerializeAsString();
25364 }
25365 
SerializeAsArray() const25366 std::vector<uint8_t> ChromeContentSettingsEventInfo::SerializeAsArray() const {
25367   ::protozero::HeapBuffered<::protozero::Message> msg;
25368   Serialize(msg.get());
25369   return msg.SerializeAsArray();
25370 }
25371 
Serialize(::protozero::Message * msg) const25372 void ChromeContentSettingsEventInfo::Serialize(::protozero::Message* msg) const {
25373   // Field 1: number_of_exceptions
25374   if (_has_field_[1]) {
25375     msg->AppendVarInt(1, number_of_exceptions_);
25376   }
25377 
25378   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
25379 }
25380 
25381 }  // namespace perfetto
25382 }  // namespace protos
25383 }  // namespace gen
25384 #if defined(__GNUC__) || defined(__clang__)
25385 #pragma GCC diagnostic pop
25386 #endif
25387 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_frame_reporter.gen.cc
25388 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_frame_reporter.gen.h
25389 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
25390 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_FRAME_REPORTER_PROTO_CPP_H_
25391 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_FRAME_REPORTER_PROTO_CPP_H_
25392 
25393 #include <stdint.h>
25394 #include <bitset>
25395 #include <vector>
25396 #include <string>
25397 #include <type_traits>
25398 
25399 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
25400 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
25401 // gen_amalgamated expanded: #include "perfetto/base/export.h"
25402 
25403 namespace perfetto {
25404 namespace protos {
25405 namespace gen {
25406 class ChromeFrameReporter;
25407 enum ChromeFrameReporter_State : int;
25408 enum ChromeFrameReporter_FrameDropReason : int;
25409 enum ChromeFrameReporter_ScrollState : int;
25410 }  // namespace perfetto
25411 }  // namespace protos
25412 }  // namespace gen
25413 
25414 namespace protozero {
25415 class Message;
25416 }  // namespace protozero
25417 
25418 namespace perfetto {
25419 namespace protos {
25420 namespace gen {
25421 enum ChromeFrameReporter_State : int {
25422   ChromeFrameReporter_State_STATE_NO_UPDATE_DESIRED = 0,
25423   ChromeFrameReporter_State_STATE_PRESENTED_ALL = 1,
25424   ChromeFrameReporter_State_STATE_PRESENTED_PARTIAL = 2,
25425   ChromeFrameReporter_State_STATE_DROPPED = 3,
25426 };
25427 enum ChromeFrameReporter_FrameDropReason : int {
25428   ChromeFrameReporter_FrameDropReason_REASON_UNSPECIFIED = 0,
25429   ChromeFrameReporter_FrameDropReason_REASON_DISPLAY_COMPOSITOR = 1,
25430   ChromeFrameReporter_FrameDropReason_REASON_MAIN_THREAD = 2,
25431   ChromeFrameReporter_FrameDropReason_REASON_CLIENT_COMPOSITOR = 3,
25432 };
25433 enum ChromeFrameReporter_ScrollState : int {
25434   ChromeFrameReporter_ScrollState_SCROLL_NONE = 0,
25435   ChromeFrameReporter_ScrollState_SCROLL_MAIN_THREAD = 1,
25436   ChromeFrameReporter_ScrollState_SCROLL_COMPOSITOR_THREAD = 2,
25437   ChromeFrameReporter_ScrollState_SCROLL_UNKNOWN = 3,
25438 };
25439 
25440 class PERFETTO_EXPORT ChromeFrameReporter : public ::protozero::CppMessageObj {
25441  public:
25442   using State = ChromeFrameReporter_State;
25443   static constexpr auto STATE_NO_UPDATE_DESIRED = ChromeFrameReporter_State_STATE_NO_UPDATE_DESIRED;
25444   static constexpr auto STATE_PRESENTED_ALL = ChromeFrameReporter_State_STATE_PRESENTED_ALL;
25445   static constexpr auto STATE_PRESENTED_PARTIAL = ChromeFrameReporter_State_STATE_PRESENTED_PARTIAL;
25446   static constexpr auto STATE_DROPPED = ChromeFrameReporter_State_STATE_DROPPED;
25447   static constexpr auto State_MIN = ChromeFrameReporter_State_STATE_NO_UPDATE_DESIRED;
25448   static constexpr auto State_MAX = ChromeFrameReporter_State_STATE_DROPPED;
25449   using FrameDropReason = ChromeFrameReporter_FrameDropReason;
25450   static constexpr auto REASON_UNSPECIFIED = ChromeFrameReporter_FrameDropReason_REASON_UNSPECIFIED;
25451   static constexpr auto REASON_DISPLAY_COMPOSITOR = ChromeFrameReporter_FrameDropReason_REASON_DISPLAY_COMPOSITOR;
25452   static constexpr auto REASON_MAIN_THREAD = ChromeFrameReporter_FrameDropReason_REASON_MAIN_THREAD;
25453   static constexpr auto REASON_CLIENT_COMPOSITOR = ChromeFrameReporter_FrameDropReason_REASON_CLIENT_COMPOSITOR;
25454   static constexpr auto FrameDropReason_MIN = ChromeFrameReporter_FrameDropReason_REASON_UNSPECIFIED;
25455   static constexpr auto FrameDropReason_MAX = ChromeFrameReporter_FrameDropReason_REASON_CLIENT_COMPOSITOR;
25456   using ScrollState = ChromeFrameReporter_ScrollState;
25457   static constexpr auto SCROLL_NONE = ChromeFrameReporter_ScrollState_SCROLL_NONE;
25458   static constexpr auto SCROLL_MAIN_THREAD = ChromeFrameReporter_ScrollState_SCROLL_MAIN_THREAD;
25459   static constexpr auto SCROLL_COMPOSITOR_THREAD = ChromeFrameReporter_ScrollState_SCROLL_COMPOSITOR_THREAD;
25460   static constexpr auto SCROLL_UNKNOWN = ChromeFrameReporter_ScrollState_SCROLL_UNKNOWN;
25461   static constexpr auto ScrollState_MIN = ChromeFrameReporter_ScrollState_SCROLL_NONE;
25462   static constexpr auto ScrollState_MAX = ChromeFrameReporter_ScrollState_SCROLL_UNKNOWN;
25463   enum FieldNumbers {
25464     kStateFieldNumber = 1,
25465     kReasonFieldNumber = 2,
25466     kFrameSourceFieldNumber = 3,
25467     kFrameSequenceFieldNumber = 4,
25468     kAffectsSmoothnessFieldNumber = 5,
25469     kScrollStateFieldNumber = 6,
25470     kHasMainAnimationFieldNumber = 7,
25471     kHasCompositorAnimationFieldNumber = 8,
25472     kHasSmoothInputMainFieldNumber = 9,
25473     kHasMissingContentFieldNumber = 10,
25474     kLayerTreeHostIdFieldNumber = 11,
25475   };
25476 
25477   ChromeFrameReporter();
25478   ~ChromeFrameReporter() override;
25479   ChromeFrameReporter(ChromeFrameReporter&&) noexcept;
25480   ChromeFrameReporter& operator=(ChromeFrameReporter&&);
25481   ChromeFrameReporter(const ChromeFrameReporter&);
25482   ChromeFrameReporter& operator=(const ChromeFrameReporter&);
25483   bool operator==(const ChromeFrameReporter&) const;
operator !=(const ChromeFrameReporter & other) const25484   bool operator!=(const ChromeFrameReporter& other) const { return !(*this == other); }
25485 
25486   bool ParseFromArray(const void*, size_t) override;
25487   std::string SerializeAsString() const override;
25488   std::vector<uint8_t> SerializeAsArray() const override;
25489   void Serialize(::protozero::Message*) const;
25490 
has_state() const25491   bool has_state() const { return _has_field_[1]; }
state() const25492   ChromeFrameReporter_State state() const { return state_; }
set_state(ChromeFrameReporter_State value)25493   void set_state(ChromeFrameReporter_State value) { state_ = value; _has_field_.set(1); }
25494 
has_reason() const25495   bool has_reason() const { return _has_field_[2]; }
reason() const25496   ChromeFrameReporter_FrameDropReason reason() const { return reason_; }
set_reason(ChromeFrameReporter_FrameDropReason value)25497   void set_reason(ChromeFrameReporter_FrameDropReason value) { reason_ = value; _has_field_.set(2); }
25498 
has_frame_source() const25499   bool has_frame_source() const { return _has_field_[3]; }
frame_source() const25500   uint64_t frame_source() const { return frame_source_; }
set_frame_source(uint64_t value)25501   void set_frame_source(uint64_t value) { frame_source_ = value; _has_field_.set(3); }
25502 
has_frame_sequence() const25503   bool has_frame_sequence() const { return _has_field_[4]; }
frame_sequence() const25504   uint64_t frame_sequence() const { return frame_sequence_; }
set_frame_sequence(uint64_t value)25505   void set_frame_sequence(uint64_t value) { frame_sequence_ = value; _has_field_.set(4); }
25506 
has_affects_smoothness() const25507   bool has_affects_smoothness() const { return _has_field_[5]; }
affects_smoothness() const25508   bool affects_smoothness() const { return affects_smoothness_; }
set_affects_smoothness(bool value)25509   void set_affects_smoothness(bool value) { affects_smoothness_ = value; _has_field_.set(5); }
25510 
has_scroll_state() const25511   bool has_scroll_state() const { return _has_field_[6]; }
scroll_state() const25512   ChromeFrameReporter_ScrollState scroll_state() const { return scroll_state_; }
set_scroll_state(ChromeFrameReporter_ScrollState value)25513   void set_scroll_state(ChromeFrameReporter_ScrollState value) { scroll_state_ = value; _has_field_.set(6); }
25514 
has_has_main_animation() const25515   bool has_has_main_animation() const { return _has_field_[7]; }
has_main_animation() const25516   bool has_main_animation() const { return has_main_animation_; }
set_has_main_animation(bool value)25517   void set_has_main_animation(bool value) { has_main_animation_ = value; _has_field_.set(7); }
25518 
has_has_compositor_animation() const25519   bool has_has_compositor_animation() const { return _has_field_[8]; }
has_compositor_animation() const25520   bool has_compositor_animation() const { return has_compositor_animation_; }
set_has_compositor_animation(bool value)25521   void set_has_compositor_animation(bool value) { has_compositor_animation_ = value; _has_field_.set(8); }
25522 
has_has_smooth_input_main() const25523   bool has_has_smooth_input_main() const { return _has_field_[9]; }
has_smooth_input_main() const25524   bool has_smooth_input_main() const { return has_smooth_input_main_; }
set_has_smooth_input_main(bool value)25525   void set_has_smooth_input_main(bool value) { has_smooth_input_main_ = value; _has_field_.set(9); }
25526 
has_has_missing_content() const25527   bool has_has_missing_content() const { return _has_field_[10]; }
has_missing_content() const25528   bool has_missing_content() const { return has_missing_content_; }
set_has_missing_content(bool value)25529   void set_has_missing_content(bool value) { has_missing_content_ = value; _has_field_.set(10); }
25530 
has_layer_tree_host_id() const25531   bool has_layer_tree_host_id() const { return _has_field_[11]; }
layer_tree_host_id() const25532   uint64_t layer_tree_host_id() const { return layer_tree_host_id_; }
set_layer_tree_host_id(uint64_t value)25533   void set_layer_tree_host_id(uint64_t value) { layer_tree_host_id_ = value; _has_field_.set(11); }
25534 
25535  private:
25536   ChromeFrameReporter_State state_{};
25537   ChromeFrameReporter_FrameDropReason reason_{};
25538   uint64_t frame_source_{};
25539   uint64_t frame_sequence_{};
25540   bool affects_smoothness_{};
25541   ChromeFrameReporter_ScrollState scroll_state_{};
25542   bool has_main_animation_{};
25543   bool has_compositor_animation_{};
25544   bool has_smooth_input_main_{};
25545   bool has_missing_content_{};
25546   uint64_t layer_tree_host_id_{};
25547 
25548   // Allows to preserve unknown protobuf fields for compatibility
25549   // with future versions of .proto files.
25550   std::string unknown_fields_;
25551 
25552   std::bitset<12> _has_field_{};
25553 };
25554 
25555 }  // namespace perfetto
25556 }  // namespace protos
25557 }  // namespace gen
25558 
25559 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_FRAME_REPORTER_PROTO_CPP_H_
25560 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
25561 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
25562 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
25563 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
25564 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
25565 #if defined(__GNUC__) || defined(__clang__)
25566 #pragma GCC diagnostic push
25567 #pragma GCC diagnostic ignored "-Wfloat-equal"
25568 #endif
25569 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_frame_reporter.gen.h"
25570 
25571 namespace perfetto {
25572 namespace protos {
25573 namespace gen {
25574 
25575 ChromeFrameReporter::ChromeFrameReporter() = default;
25576 ChromeFrameReporter::~ChromeFrameReporter() = default;
25577 ChromeFrameReporter::ChromeFrameReporter(const ChromeFrameReporter&) = default;
25578 ChromeFrameReporter& ChromeFrameReporter::operator=(const ChromeFrameReporter&) = default;
25579 ChromeFrameReporter::ChromeFrameReporter(ChromeFrameReporter&&) noexcept = default;
25580 ChromeFrameReporter& ChromeFrameReporter::operator=(ChromeFrameReporter&&) = default;
25581 
operator ==(const ChromeFrameReporter & other) const25582 bool ChromeFrameReporter::operator==(const ChromeFrameReporter& other) const {
25583   return unknown_fields_ == other.unknown_fields_
25584    && state_ == other.state_
25585    && reason_ == other.reason_
25586    && frame_source_ == other.frame_source_
25587    && frame_sequence_ == other.frame_sequence_
25588    && affects_smoothness_ == other.affects_smoothness_
25589    && scroll_state_ == other.scroll_state_
25590    && has_main_animation_ == other.has_main_animation_
25591    && has_compositor_animation_ == other.has_compositor_animation_
25592    && has_smooth_input_main_ == other.has_smooth_input_main_
25593    && has_missing_content_ == other.has_missing_content_
25594    && layer_tree_host_id_ == other.layer_tree_host_id_;
25595 }
25596 
ParseFromArray(const void * raw,size_t size)25597 bool ChromeFrameReporter::ParseFromArray(const void* raw, size_t size) {
25598   unknown_fields_.clear();
25599   bool packed_error = false;
25600 
25601   ::protozero::ProtoDecoder dec(raw, size);
25602   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
25603     if (field.id() < _has_field_.size()) {
25604       _has_field_.set(field.id());
25605     }
25606     switch (field.id()) {
25607       case 1 /* state */:
25608         field.get(&state_);
25609         break;
25610       case 2 /* reason */:
25611         field.get(&reason_);
25612         break;
25613       case 3 /* frame_source */:
25614         field.get(&frame_source_);
25615         break;
25616       case 4 /* frame_sequence */:
25617         field.get(&frame_sequence_);
25618         break;
25619       case 5 /* affects_smoothness */:
25620         field.get(&affects_smoothness_);
25621         break;
25622       case 6 /* scroll_state */:
25623         field.get(&scroll_state_);
25624         break;
25625       case 7 /* has_main_animation */:
25626         field.get(&has_main_animation_);
25627         break;
25628       case 8 /* has_compositor_animation */:
25629         field.get(&has_compositor_animation_);
25630         break;
25631       case 9 /* has_smooth_input_main */:
25632         field.get(&has_smooth_input_main_);
25633         break;
25634       case 10 /* has_missing_content */:
25635         field.get(&has_missing_content_);
25636         break;
25637       case 11 /* layer_tree_host_id */:
25638         field.get(&layer_tree_host_id_);
25639         break;
25640       default:
25641         field.SerializeAndAppendTo(&unknown_fields_);
25642         break;
25643     }
25644   }
25645   return !packed_error && !dec.bytes_left();
25646 }
25647 
SerializeAsString() const25648 std::string ChromeFrameReporter::SerializeAsString() const {
25649   ::protozero::HeapBuffered<::protozero::Message> msg;
25650   Serialize(msg.get());
25651   return msg.SerializeAsString();
25652 }
25653 
SerializeAsArray() const25654 std::vector<uint8_t> ChromeFrameReporter::SerializeAsArray() const {
25655   ::protozero::HeapBuffered<::protozero::Message> msg;
25656   Serialize(msg.get());
25657   return msg.SerializeAsArray();
25658 }
25659 
Serialize(::protozero::Message * msg) const25660 void ChromeFrameReporter::Serialize(::protozero::Message* msg) const {
25661   // Field 1: state
25662   if (_has_field_[1]) {
25663     msg->AppendVarInt(1, state_);
25664   }
25665 
25666   // Field 2: reason
25667   if (_has_field_[2]) {
25668     msg->AppendVarInt(2, reason_);
25669   }
25670 
25671   // Field 3: frame_source
25672   if (_has_field_[3]) {
25673     msg->AppendVarInt(3, frame_source_);
25674   }
25675 
25676   // Field 4: frame_sequence
25677   if (_has_field_[4]) {
25678     msg->AppendVarInt(4, frame_sequence_);
25679   }
25680 
25681   // Field 5: affects_smoothness
25682   if (_has_field_[5]) {
25683     msg->AppendTinyVarInt(5, affects_smoothness_);
25684   }
25685 
25686   // Field 6: scroll_state
25687   if (_has_field_[6]) {
25688     msg->AppendVarInt(6, scroll_state_);
25689   }
25690 
25691   // Field 7: has_main_animation
25692   if (_has_field_[7]) {
25693     msg->AppendTinyVarInt(7, has_main_animation_);
25694   }
25695 
25696   // Field 8: has_compositor_animation
25697   if (_has_field_[8]) {
25698     msg->AppendTinyVarInt(8, has_compositor_animation_);
25699   }
25700 
25701   // Field 9: has_smooth_input_main
25702   if (_has_field_[9]) {
25703     msg->AppendTinyVarInt(9, has_smooth_input_main_);
25704   }
25705 
25706   // Field 10: has_missing_content
25707   if (_has_field_[10]) {
25708     msg->AppendTinyVarInt(10, has_missing_content_);
25709   }
25710 
25711   // Field 11: layer_tree_host_id
25712   if (_has_field_[11]) {
25713     msg->AppendVarInt(11, layer_tree_host_id_);
25714   }
25715 
25716   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
25717 }
25718 
25719 }  // namespace perfetto
25720 }  // namespace protos
25721 }  // namespace gen
25722 #if defined(__GNUC__) || defined(__clang__)
25723 #pragma GCC diagnostic pop
25724 #endif
25725 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_histogram_sample.gen.cc
25726 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_histogram_sample.gen.h
25727 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
25728 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_HISTOGRAM_SAMPLE_PROTO_CPP_H_
25729 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_HISTOGRAM_SAMPLE_PROTO_CPP_H_
25730 
25731 #include <stdint.h>
25732 #include <bitset>
25733 #include <vector>
25734 #include <string>
25735 #include <type_traits>
25736 
25737 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
25738 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
25739 // gen_amalgamated expanded: #include "perfetto/base/export.h"
25740 
25741 namespace perfetto {
25742 namespace protos {
25743 namespace gen {
25744 class ChromeHistogramSample;
25745 class HistogramName;
25746 }  // namespace perfetto
25747 }  // namespace protos
25748 }  // namespace gen
25749 
25750 namespace protozero {
25751 class Message;
25752 }  // namespace protozero
25753 
25754 namespace perfetto {
25755 namespace protos {
25756 namespace gen {
25757 
25758 class PERFETTO_EXPORT ChromeHistogramSample : public ::protozero::CppMessageObj {
25759  public:
25760   enum FieldNumbers {
25761     kNameHashFieldNumber = 1,
25762     kNameFieldNumber = 2,
25763     kSampleFieldNumber = 3,
25764     kNameIidFieldNumber = 4,
25765   };
25766 
25767   ChromeHistogramSample();
25768   ~ChromeHistogramSample() override;
25769   ChromeHistogramSample(ChromeHistogramSample&&) noexcept;
25770   ChromeHistogramSample& operator=(ChromeHistogramSample&&);
25771   ChromeHistogramSample(const ChromeHistogramSample&);
25772   ChromeHistogramSample& operator=(const ChromeHistogramSample&);
25773   bool operator==(const ChromeHistogramSample&) const;
operator !=(const ChromeHistogramSample & other) const25774   bool operator!=(const ChromeHistogramSample& other) const { return !(*this == other); }
25775 
25776   bool ParseFromArray(const void*, size_t) override;
25777   std::string SerializeAsString() const override;
25778   std::vector<uint8_t> SerializeAsArray() const override;
25779   void Serialize(::protozero::Message*) const;
25780 
has_name_hash() const25781   bool has_name_hash() const { return _has_field_[1]; }
name_hash() const25782   uint64_t name_hash() const { return name_hash_; }
set_name_hash(uint64_t value)25783   void set_name_hash(uint64_t value) { name_hash_ = value; _has_field_.set(1); }
25784 
has_name() const25785   bool has_name() const { return _has_field_[2]; }
name() const25786   const std::string& name() const { return name_; }
set_name(const std::string & value)25787   void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
25788 
has_sample() const25789   bool has_sample() const { return _has_field_[3]; }
sample() const25790   int64_t sample() const { return sample_; }
set_sample(int64_t value)25791   void set_sample(int64_t value) { sample_ = value; _has_field_.set(3); }
25792 
has_name_iid() const25793   bool has_name_iid() const { return _has_field_[4]; }
name_iid() const25794   uint64_t name_iid() const { return name_iid_; }
set_name_iid(uint64_t value)25795   void set_name_iid(uint64_t value) { name_iid_ = value; _has_field_.set(4); }
25796 
25797  private:
25798   uint64_t name_hash_{};
25799   std::string name_{};
25800   int64_t sample_{};
25801   uint64_t name_iid_{};
25802 
25803   // Allows to preserve unknown protobuf fields for compatibility
25804   // with future versions of .proto files.
25805   std::string unknown_fields_;
25806 
25807   std::bitset<5> _has_field_{};
25808 };
25809 
25810 
25811 class PERFETTO_EXPORT HistogramName : public ::protozero::CppMessageObj {
25812  public:
25813   enum FieldNumbers {
25814     kIidFieldNumber = 1,
25815     kNameFieldNumber = 2,
25816   };
25817 
25818   HistogramName();
25819   ~HistogramName() override;
25820   HistogramName(HistogramName&&) noexcept;
25821   HistogramName& operator=(HistogramName&&);
25822   HistogramName(const HistogramName&);
25823   HistogramName& operator=(const HistogramName&);
25824   bool operator==(const HistogramName&) const;
operator !=(const HistogramName & other) const25825   bool operator!=(const HistogramName& other) const { return !(*this == other); }
25826 
25827   bool ParseFromArray(const void*, size_t) override;
25828   std::string SerializeAsString() const override;
25829   std::vector<uint8_t> SerializeAsArray() const override;
25830   void Serialize(::protozero::Message*) const;
25831 
has_iid() const25832   bool has_iid() const { return _has_field_[1]; }
iid() const25833   uint64_t iid() const { return iid_; }
set_iid(uint64_t value)25834   void set_iid(uint64_t value) { iid_ = value; _has_field_.set(1); }
25835 
has_name() const25836   bool has_name() const { return _has_field_[2]; }
name() const25837   const std::string& name() const { return name_; }
set_name(const std::string & value)25838   void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
25839 
25840  private:
25841   uint64_t iid_{};
25842   std::string name_{};
25843 
25844   // Allows to preserve unknown protobuf fields for compatibility
25845   // with future versions of .proto files.
25846   std::string unknown_fields_;
25847 
25848   std::bitset<3> _has_field_{};
25849 };
25850 
25851 }  // namespace perfetto
25852 }  // namespace protos
25853 }  // namespace gen
25854 
25855 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_HISTOGRAM_SAMPLE_PROTO_CPP_H_
25856 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
25857 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
25858 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
25859 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
25860 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
25861 #if defined(__GNUC__) || defined(__clang__)
25862 #pragma GCC diagnostic push
25863 #pragma GCC diagnostic ignored "-Wfloat-equal"
25864 #endif
25865 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_histogram_sample.gen.h"
25866 
25867 namespace perfetto {
25868 namespace protos {
25869 namespace gen {
25870 
25871 ChromeHistogramSample::ChromeHistogramSample() = default;
25872 ChromeHistogramSample::~ChromeHistogramSample() = default;
25873 ChromeHistogramSample::ChromeHistogramSample(const ChromeHistogramSample&) = default;
25874 ChromeHistogramSample& ChromeHistogramSample::operator=(const ChromeHistogramSample&) = default;
25875 ChromeHistogramSample::ChromeHistogramSample(ChromeHistogramSample&&) noexcept = default;
25876 ChromeHistogramSample& ChromeHistogramSample::operator=(ChromeHistogramSample&&) = default;
25877 
operator ==(const ChromeHistogramSample & other) const25878 bool ChromeHistogramSample::operator==(const ChromeHistogramSample& other) const {
25879   return unknown_fields_ == other.unknown_fields_
25880    && name_hash_ == other.name_hash_
25881    && name_ == other.name_
25882    && sample_ == other.sample_
25883    && name_iid_ == other.name_iid_;
25884 }
25885 
ParseFromArray(const void * raw,size_t size)25886 bool ChromeHistogramSample::ParseFromArray(const void* raw, size_t size) {
25887   unknown_fields_.clear();
25888   bool packed_error = false;
25889 
25890   ::protozero::ProtoDecoder dec(raw, size);
25891   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
25892     if (field.id() < _has_field_.size()) {
25893       _has_field_.set(field.id());
25894     }
25895     switch (field.id()) {
25896       case 1 /* name_hash */:
25897         field.get(&name_hash_);
25898         break;
25899       case 2 /* name */:
25900         field.get(&name_);
25901         break;
25902       case 3 /* sample */:
25903         field.get(&sample_);
25904         break;
25905       case 4 /* name_iid */:
25906         field.get(&name_iid_);
25907         break;
25908       default:
25909         field.SerializeAndAppendTo(&unknown_fields_);
25910         break;
25911     }
25912   }
25913   return !packed_error && !dec.bytes_left();
25914 }
25915 
SerializeAsString() const25916 std::string ChromeHistogramSample::SerializeAsString() const {
25917   ::protozero::HeapBuffered<::protozero::Message> msg;
25918   Serialize(msg.get());
25919   return msg.SerializeAsString();
25920 }
25921 
SerializeAsArray() const25922 std::vector<uint8_t> ChromeHistogramSample::SerializeAsArray() const {
25923   ::protozero::HeapBuffered<::protozero::Message> msg;
25924   Serialize(msg.get());
25925   return msg.SerializeAsArray();
25926 }
25927 
Serialize(::protozero::Message * msg) const25928 void ChromeHistogramSample::Serialize(::protozero::Message* msg) const {
25929   // Field 1: name_hash
25930   if (_has_field_[1]) {
25931     msg->AppendVarInt(1, name_hash_);
25932   }
25933 
25934   // Field 2: name
25935   if (_has_field_[2]) {
25936     msg->AppendString(2, name_);
25937   }
25938 
25939   // Field 3: sample
25940   if (_has_field_[3]) {
25941     msg->AppendVarInt(3, sample_);
25942   }
25943 
25944   // Field 4: name_iid
25945   if (_has_field_[4]) {
25946     msg->AppendVarInt(4, name_iid_);
25947   }
25948 
25949   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
25950 }
25951 
25952 
25953 HistogramName::HistogramName() = default;
25954 HistogramName::~HistogramName() = default;
25955 HistogramName::HistogramName(const HistogramName&) = default;
25956 HistogramName& HistogramName::operator=(const HistogramName&) = default;
25957 HistogramName::HistogramName(HistogramName&&) noexcept = default;
25958 HistogramName& HistogramName::operator=(HistogramName&&) = default;
25959 
operator ==(const HistogramName & other) const25960 bool HistogramName::operator==(const HistogramName& other) const {
25961   return unknown_fields_ == other.unknown_fields_
25962    && iid_ == other.iid_
25963    && name_ == other.name_;
25964 }
25965 
ParseFromArray(const void * raw,size_t size)25966 bool HistogramName::ParseFromArray(const void* raw, size_t size) {
25967   unknown_fields_.clear();
25968   bool packed_error = false;
25969 
25970   ::protozero::ProtoDecoder dec(raw, size);
25971   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
25972     if (field.id() < _has_field_.size()) {
25973       _has_field_.set(field.id());
25974     }
25975     switch (field.id()) {
25976       case 1 /* iid */:
25977         field.get(&iid_);
25978         break;
25979       case 2 /* name */:
25980         field.get(&name_);
25981         break;
25982       default:
25983         field.SerializeAndAppendTo(&unknown_fields_);
25984         break;
25985     }
25986   }
25987   return !packed_error && !dec.bytes_left();
25988 }
25989 
SerializeAsString() const25990 std::string HistogramName::SerializeAsString() const {
25991   ::protozero::HeapBuffered<::protozero::Message> msg;
25992   Serialize(msg.get());
25993   return msg.SerializeAsString();
25994 }
25995 
SerializeAsArray() const25996 std::vector<uint8_t> HistogramName::SerializeAsArray() const {
25997   ::protozero::HeapBuffered<::protozero::Message> msg;
25998   Serialize(msg.get());
25999   return msg.SerializeAsArray();
26000 }
26001 
Serialize(::protozero::Message * msg) const26002 void HistogramName::Serialize(::protozero::Message* msg) const {
26003   // Field 1: iid
26004   if (_has_field_[1]) {
26005     msg->AppendVarInt(1, iid_);
26006   }
26007 
26008   // Field 2: name
26009   if (_has_field_[2]) {
26010     msg->AppendString(2, name_);
26011   }
26012 
26013   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
26014 }
26015 
26016 }  // namespace perfetto
26017 }  // namespace protos
26018 }  // namespace gen
26019 #if defined(__GNUC__) || defined(__clang__)
26020 #pragma GCC diagnostic pop
26021 #endif
26022 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_keyed_service.gen.cc
26023 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_keyed_service.gen.h
26024 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
26025 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_KEYED_SERVICE_PROTO_CPP_H_
26026 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_KEYED_SERVICE_PROTO_CPP_H_
26027 
26028 #include <stdint.h>
26029 #include <bitset>
26030 #include <vector>
26031 #include <string>
26032 #include <type_traits>
26033 
26034 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
26035 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
26036 // gen_amalgamated expanded: #include "perfetto/base/export.h"
26037 
26038 namespace perfetto {
26039 namespace protos {
26040 namespace gen {
26041 class ChromeKeyedService;
26042 }  // namespace perfetto
26043 }  // namespace protos
26044 }  // namespace gen
26045 
26046 namespace protozero {
26047 class Message;
26048 }  // namespace protozero
26049 
26050 namespace perfetto {
26051 namespace protos {
26052 namespace gen {
26053 
26054 class PERFETTO_EXPORT ChromeKeyedService : public ::protozero::CppMessageObj {
26055  public:
26056   enum FieldNumbers {
26057     kNameFieldNumber = 1,
26058   };
26059 
26060   ChromeKeyedService();
26061   ~ChromeKeyedService() override;
26062   ChromeKeyedService(ChromeKeyedService&&) noexcept;
26063   ChromeKeyedService& operator=(ChromeKeyedService&&);
26064   ChromeKeyedService(const ChromeKeyedService&);
26065   ChromeKeyedService& operator=(const ChromeKeyedService&);
26066   bool operator==(const ChromeKeyedService&) const;
operator !=(const ChromeKeyedService & other) const26067   bool operator!=(const ChromeKeyedService& other) const { return !(*this == other); }
26068 
26069   bool ParseFromArray(const void*, size_t) override;
26070   std::string SerializeAsString() const override;
26071   std::vector<uint8_t> SerializeAsArray() const override;
26072   void Serialize(::protozero::Message*) const;
26073 
has_name() const26074   bool has_name() const { return _has_field_[1]; }
name() const26075   const std::string& name() const { return name_; }
set_name(const std::string & value)26076   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
26077 
26078  private:
26079   std::string name_{};
26080 
26081   // Allows to preserve unknown protobuf fields for compatibility
26082   // with future versions of .proto files.
26083   std::string unknown_fields_;
26084 
26085   std::bitset<2> _has_field_{};
26086 };
26087 
26088 }  // namespace perfetto
26089 }  // namespace protos
26090 }  // namespace gen
26091 
26092 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_KEYED_SERVICE_PROTO_CPP_H_
26093 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
26094 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
26095 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
26096 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
26097 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
26098 #if defined(__GNUC__) || defined(__clang__)
26099 #pragma GCC diagnostic push
26100 #pragma GCC diagnostic ignored "-Wfloat-equal"
26101 #endif
26102 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_keyed_service.gen.h"
26103 
26104 namespace perfetto {
26105 namespace protos {
26106 namespace gen {
26107 
26108 ChromeKeyedService::ChromeKeyedService() = default;
26109 ChromeKeyedService::~ChromeKeyedService() = default;
26110 ChromeKeyedService::ChromeKeyedService(const ChromeKeyedService&) = default;
26111 ChromeKeyedService& ChromeKeyedService::operator=(const ChromeKeyedService&) = default;
26112 ChromeKeyedService::ChromeKeyedService(ChromeKeyedService&&) noexcept = default;
26113 ChromeKeyedService& ChromeKeyedService::operator=(ChromeKeyedService&&) = default;
26114 
operator ==(const ChromeKeyedService & other) const26115 bool ChromeKeyedService::operator==(const ChromeKeyedService& other) const {
26116   return unknown_fields_ == other.unknown_fields_
26117    && name_ == other.name_;
26118 }
26119 
ParseFromArray(const void * raw,size_t size)26120 bool ChromeKeyedService::ParseFromArray(const void* raw, size_t size) {
26121   unknown_fields_.clear();
26122   bool packed_error = false;
26123 
26124   ::protozero::ProtoDecoder dec(raw, size);
26125   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
26126     if (field.id() < _has_field_.size()) {
26127       _has_field_.set(field.id());
26128     }
26129     switch (field.id()) {
26130       case 1 /* name */:
26131         field.get(&name_);
26132         break;
26133       default:
26134         field.SerializeAndAppendTo(&unknown_fields_);
26135         break;
26136     }
26137   }
26138   return !packed_error && !dec.bytes_left();
26139 }
26140 
SerializeAsString() const26141 std::string ChromeKeyedService::SerializeAsString() const {
26142   ::protozero::HeapBuffered<::protozero::Message> msg;
26143   Serialize(msg.get());
26144   return msg.SerializeAsString();
26145 }
26146 
SerializeAsArray() const26147 std::vector<uint8_t> ChromeKeyedService::SerializeAsArray() const {
26148   ::protozero::HeapBuffered<::protozero::Message> msg;
26149   Serialize(msg.get());
26150   return msg.SerializeAsArray();
26151 }
26152 
Serialize(::protozero::Message * msg) const26153 void ChromeKeyedService::Serialize(::protozero::Message* msg) const {
26154   // Field 1: name
26155   if (_has_field_[1]) {
26156     msg->AppendString(1, name_);
26157   }
26158 
26159   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
26160 }
26161 
26162 }  // namespace perfetto
26163 }  // namespace protos
26164 }  // namespace gen
26165 #if defined(__GNUC__) || defined(__clang__)
26166 #pragma GCC diagnostic pop
26167 #endif
26168 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_latency_info.gen.cc
26169 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_latency_info.gen.h
26170 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
26171 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LATENCY_INFO_PROTO_CPP_H_
26172 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LATENCY_INFO_PROTO_CPP_H_
26173 
26174 #include <stdint.h>
26175 #include <bitset>
26176 #include <vector>
26177 #include <string>
26178 #include <type_traits>
26179 
26180 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
26181 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
26182 // gen_amalgamated expanded: #include "perfetto/base/export.h"
26183 
26184 namespace perfetto {
26185 namespace protos {
26186 namespace gen {
26187 class ChromeLatencyInfo;
26188 class ChromeLatencyInfo_ComponentInfo;
26189 enum ChromeLatencyInfo_Step : int;
26190 enum ChromeLatencyInfo_LatencyComponentType : int;
26191 }  // namespace perfetto
26192 }  // namespace protos
26193 }  // namespace gen
26194 
26195 namespace protozero {
26196 class Message;
26197 }  // namespace protozero
26198 
26199 namespace perfetto {
26200 namespace protos {
26201 namespace gen {
26202 enum ChromeLatencyInfo_Step : int {
26203   ChromeLatencyInfo_Step_STEP_UNSPECIFIED = 0,
26204   ChromeLatencyInfo_Step_STEP_SEND_INPUT_EVENT_UI = 3,
26205   ChromeLatencyInfo_Step_STEP_HANDLE_INPUT_EVENT_IMPL = 5,
26206   ChromeLatencyInfo_Step_STEP_DID_HANDLE_INPUT_AND_OVERSCROLL = 8,
26207   ChromeLatencyInfo_Step_STEP_HANDLE_INPUT_EVENT_MAIN = 4,
26208   ChromeLatencyInfo_Step_STEP_MAIN_THREAD_SCROLL_UPDATE = 2,
26209   ChromeLatencyInfo_Step_STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT = 1,
26210   ChromeLatencyInfo_Step_STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL = 9,
26211   ChromeLatencyInfo_Step_STEP_HANDLED_INPUT_EVENT_IMPL = 10,
26212   ChromeLatencyInfo_Step_STEP_SWAP_BUFFERS = 6,
26213   ChromeLatencyInfo_Step_STEP_DRAW_AND_SWAP = 7,
26214   ChromeLatencyInfo_Step_STEP_FINISHED_SWAP_BUFFERS = 11,
26215 };
26216 enum ChromeLatencyInfo_LatencyComponentType : int {
26217   ChromeLatencyInfo_LatencyComponentType_COMPONENT_UNSPECIFIED = 0,
26218   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH = 1,
26219   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL = 2,
26220   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL = 3,
26221   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_ORIGINAL = 4,
26222   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_UI = 5,
26223   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERER_MAIN = 6,
26224   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN = 7,
26225   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL = 8,
26226   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_LAST_EVENT = 9,
26227   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_ACK_RWH = 10,
26228   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERER_SWAP = 11,
26229   ChromeLatencyInfo_LatencyComponentType_COMPONENT_DISPLAY_COMPOSITOR_RECEIVED_FRAME = 12,
26230   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_GPU_SWAP_BUFFER = 13,
26231   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP = 14,
26232 };
26233 
26234 class PERFETTO_EXPORT ChromeLatencyInfo : public ::protozero::CppMessageObj {
26235  public:
26236   using ComponentInfo = ChromeLatencyInfo_ComponentInfo;
26237   using Step = ChromeLatencyInfo_Step;
26238   static constexpr auto STEP_UNSPECIFIED = ChromeLatencyInfo_Step_STEP_UNSPECIFIED;
26239   static constexpr auto STEP_SEND_INPUT_EVENT_UI = ChromeLatencyInfo_Step_STEP_SEND_INPUT_EVENT_UI;
26240   static constexpr auto STEP_HANDLE_INPUT_EVENT_IMPL = ChromeLatencyInfo_Step_STEP_HANDLE_INPUT_EVENT_IMPL;
26241   static constexpr auto STEP_DID_HANDLE_INPUT_AND_OVERSCROLL = ChromeLatencyInfo_Step_STEP_DID_HANDLE_INPUT_AND_OVERSCROLL;
26242   static constexpr auto STEP_HANDLE_INPUT_EVENT_MAIN = ChromeLatencyInfo_Step_STEP_HANDLE_INPUT_EVENT_MAIN;
26243   static constexpr auto STEP_MAIN_THREAD_SCROLL_UPDATE = ChromeLatencyInfo_Step_STEP_MAIN_THREAD_SCROLL_UPDATE;
26244   static constexpr auto STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT = ChromeLatencyInfo_Step_STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT;
26245   static constexpr auto STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL = ChromeLatencyInfo_Step_STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL;
26246   static constexpr auto STEP_HANDLED_INPUT_EVENT_IMPL = ChromeLatencyInfo_Step_STEP_HANDLED_INPUT_EVENT_IMPL;
26247   static constexpr auto STEP_SWAP_BUFFERS = ChromeLatencyInfo_Step_STEP_SWAP_BUFFERS;
26248   static constexpr auto STEP_DRAW_AND_SWAP = ChromeLatencyInfo_Step_STEP_DRAW_AND_SWAP;
26249   static constexpr auto STEP_FINISHED_SWAP_BUFFERS = ChromeLatencyInfo_Step_STEP_FINISHED_SWAP_BUFFERS;
26250   static constexpr auto Step_MIN = ChromeLatencyInfo_Step_STEP_UNSPECIFIED;
26251   static constexpr auto Step_MAX = ChromeLatencyInfo_Step_STEP_FINISHED_SWAP_BUFFERS;
26252   using LatencyComponentType = ChromeLatencyInfo_LatencyComponentType;
26253   static constexpr auto COMPONENT_UNSPECIFIED = ChromeLatencyInfo_LatencyComponentType_COMPONENT_UNSPECIFIED;
26254   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH;
26255   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL;
26256   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL;
26257   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_ORIGINAL = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_ORIGINAL;
26258   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_UI = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_UI;
26259   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_RENDERER_MAIN = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERER_MAIN;
26260   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN;
26261   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL;
26262   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_LAST_EVENT = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_LAST_EVENT;
26263   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_ACK_RWH = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_ACK_RWH;
26264   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_RENDERER_SWAP = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERER_SWAP;
26265   static constexpr auto COMPONENT_DISPLAY_COMPOSITOR_RECEIVED_FRAME = ChromeLatencyInfo_LatencyComponentType_COMPONENT_DISPLAY_COMPOSITOR_RECEIVED_FRAME;
26266   static constexpr auto COMPONENT_INPUT_EVENT_GPU_SWAP_BUFFER = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_GPU_SWAP_BUFFER;
26267   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP;
26268   static constexpr auto LatencyComponentType_MIN = ChromeLatencyInfo_LatencyComponentType_COMPONENT_UNSPECIFIED;
26269   static constexpr auto LatencyComponentType_MAX = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP;
26270   enum FieldNumbers {
26271     kTraceIdFieldNumber = 1,
26272     kStepFieldNumber = 2,
26273     kFrameTreeNodeIdFieldNumber = 3,
26274     kComponentInfoFieldNumber = 4,
26275     kIsCoalescedFieldNumber = 5,
26276     kGestureScrollIdFieldNumber = 6,
26277   };
26278 
26279   ChromeLatencyInfo();
26280   ~ChromeLatencyInfo() override;
26281   ChromeLatencyInfo(ChromeLatencyInfo&&) noexcept;
26282   ChromeLatencyInfo& operator=(ChromeLatencyInfo&&);
26283   ChromeLatencyInfo(const ChromeLatencyInfo&);
26284   ChromeLatencyInfo& operator=(const ChromeLatencyInfo&);
26285   bool operator==(const ChromeLatencyInfo&) const;
operator !=(const ChromeLatencyInfo & other) const26286   bool operator!=(const ChromeLatencyInfo& other) const { return !(*this == other); }
26287 
26288   bool ParseFromArray(const void*, size_t) override;
26289   std::string SerializeAsString() const override;
26290   std::vector<uint8_t> SerializeAsArray() const override;
26291   void Serialize(::protozero::Message*) const;
26292 
has_trace_id() const26293   bool has_trace_id() const { return _has_field_[1]; }
trace_id() const26294   int64_t trace_id() const { return trace_id_; }
set_trace_id(int64_t value)26295   void set_trace_id(int64_t value) { trace_id_ = value; _has_field_.set(1); }
26296 
has_step() const26297   bool has_step() const { return _has_field_[2]; }
step() const26298   ChromeLatencyInfo_Step step() const { return step_; }
set_step(ChromeLatencyInfo_Step value)26299   void set_step(ChromeLatencyInfo_Step value) { step_ = value; _has_field_.set(2); }
26300 
has_frame_tree_node_id() const26301   bool has_frame_tree_node_id() const { return _has_field_[3]; }
frame_tree_node_id() const26302   int32_t frame_tree_node_id() const { return frame_tree_node_id_; }
set_frame_tree_node_id(int32_t value)26303   void set_frame_tree_node_id(int32_t value) { frame_tree_node_id_ = value; _has_field_.set(3); }
26304 
component_info() const26305   const std::vector<ChromeLatencyInfo_ComponentInfo>& component_info() const { return component_info_; }
mutable_component_info()26306   std::vector<ChromeLatencyInfo_ComponentInfo>* mutable_component_info() { return &component_info_; }
26307   int component_info_size() const;
26308   void clear_component_info();
26309   ChromeLatencyInfo_ComponentInfo* add_component_info();
26310 
has_is_coalesced() const26311   bool has_is_coalesced() const { return _has_field_[5]; }
is_coalesced() const26312   bool is_coalesced() const { return is_coalesced_; }
set_is_coalesced(bool value)26313   void set_is_coalesced(bool value) { is_coalesced_ = value; _has_field_.set(5); }
26314 
has_gesture_scroll_id() const26315   bool has_gesture_scroll_id() const { return _has_field_[6]; }
gesture_scroll_id() const26316   int64_t gesture_scroll_id() const { return gesture_scroll_id_; }
set_gesture_scroll_id(int64_t value)26317   void set_gesture_scroll_id(int64_t value) { gesture_scroll_id_ = value; _has_field_.set(6); }
26318 
26319  private:
26320   int64_t trace_id_{};
26321   ChromeLatencyInfo_Step step_{};
26322   int32_t frame_tree_node_id_{};
26323   std::vector<ChromeLatencyInfo_ComponentInfo> component_info_;
26324   bool is_coalesced_{};
26325   int64_t gesture_scroll_id_{};
26326 
26327   // Allows to preserve unknown protobuf fields for compatibility
26328   // with future versions of .proto files.
26329   std::string unknown_fields_;
26330 
26331   std::bitset<7> _has_field_{};
26332 };
26333 
26334 
26335 class PERFETTO_EXPORT ChromeLatencyInfo_ComponentInfo : public ::protozero::CppMessageObj {
26336  public:
26337   enum FieldNumbers {
26338     kComponentTypeFieldNumber = 1,
26339     kTimeUsFieldNumber = 2,
26340   };
26341 
26342   ChromeLatencyInfo_ComponentInfo();
26343   ~ChromeLatencyInfo_ComponentInfo() override;
26344   ChromeLatencyInfo_ComponentInfo(ChromeLatencyInfo_ComponentInfo&&) noexcept;
26345   ChromeLatencyInfo_ComponentInfo& operator=(ChromeLatencyInfo_ComponentInfo&&);
26346   ChromeLatencyInfo_ComponentInfo(const ChromeLatencyInfo_ComponentInfo&);
26347   ChromeLatencyInfo_ComponentInfo& operator=(const ChromeLatencyInfo_ComponentInfo&);
26348   bool operator==(const ChromeLatencyInfo_ComponentInfo&) const;
operator !=(const ChromeLatencyInfo_ComponentInfo & other) const26349   bool operator!=(const ChromeLatencyInfo_ComponentInfo& other) const { return !(*this == other); }
26350 
26351   bool ParseFromArray(const void*, size_t) override;
26352   std::string SerializeAsString() const override;
26353   std::vector<uint8_t> SerializeAsArray() const override;
26354   void Serialize(::protozero::Message*) const;
26355 
has_component_type() const26356   bool has_component_type() const { return _has_field_[1]; }
component_type() const26357   ChromeLatencyInfo_LatencyComponentType component_type() const { return component_type_; }
set_component_type(ChromeLatencyInfo_LatencyComponentType value)26358   void set_component_type(ChromeLatencyInfo_LatencyComponentType value) { component_type_ = value; _has_field_.set(1); }
26359 
has_time_us() const26360   bool has_time_us() const { return _has_field_[2]; }
time_us() const26361   uint64_t time_us() const { return time_us_; }
set_time_us(uint64_t value)26362   void set_time_us(uint64_t value) { time_us_ = value; _has_field_.set(2); }
26363 
26364  private:
26365   ChromeLatencyInfo_LatencyComponentType component_type_{};
26366   uint64_t time_us_{};
26367 
26368   // Allows to preserve unknown protobuf fields for compatibility
26369   // with future versions of .proto files.
26370   std::string unknown_fields_;
26371 
26372   std::bitset<3> _has_field_{};
26373 };
26374 
26375 }  // namespace perfetto
26376 }  // namespace protos
26377 }  // namespace gen
26378 
26379 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LATENCY_INFO_PROTO_CPP_H_
26380 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
26381 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
26382 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
26383 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
26384 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
26385 #if defined(__GNUC__) || defined(__clang__)
26386 #pragma GCC diagnostic push
26387 #pragma GCC diagnostic ignored "-Wfloat-equal"
26388 #endif
26389 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_latency_info.gen.h"
26390 
26391 namespace perfetto {
26392 namespace protos {
26393 namespace gen {
26394 
26395 ChromeLatencyInfo::ChromeLatencyInfo() = default;
26396 ChromeLatencyInfo::~ChromeLatencyInfo() = default;
26397 ChromeLatencyInfo::ChromeLatencyInfo(const ChromeLatencyInfo&) = default;
26398 ChromeLatencyInfo& ChromeLatencyInfo::operator=(const ChromeLatencyInfo&) = default;
26399 ChromeLatencyInfo::ChromeLatencyInfo(ChromeLatencyInfo&&) noexcept = default;
26400 ChromeLatencyInfo& ChromeLatencyInfo::operator=(ChromeLatencyInfo&&) = default;
26401 
operator ==(const ChromeLatencyInfo & other) const26402 bool ChromeLatencyInfo::operator==(const ChromeLatencyInfo& other) const {
26403   return unknown_fields_ == other.unknown_fields_
26404    && trace_id_ == other.trace_id_
26405    && step_ == other.step_
26406    && frame_tree_node_id_ == other.frame_tree_node_id_
26407    && component_info_ == other.component_info_
26408    && is_coalesced_ == other.is_coalesced_
26409    && gesture_scroll_id_ == other.gesture_scroll_id_;
26410 }
26411 
component_info_size() const26412 int ChromeLatencyInfo::component_info_size() const { return static_cast<int>(component_info_.size()); }
clear_component_info()26413 void ChromeLatencyInfo::clear_component_info() { component_info_.clear(); }
add_component_info()26414 ChromeLatencyInfo_ComponentInfo* ChromeLatencyInfo::add_component_info() { component_info_.emplace_back(); return &component_info_.back(); }
ParseFromArray(const void * raw,size_t size)26415 bool ChromeLatencyInfo::ParseFromArray(const void* raw, size_t size) {
26416   component_info_.clear();
26417   unknown_fields_.clear();
26418   bool packed_error = false;
26419 
26420   ::protozero::ProtoDecoder dec(raw, size);
26421   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
26422     if (field.id() < _has_field_.size()) {
26423       _has_field_.set(field.id());
26424     }
26425     switch (field.id()) {
26426       case 1 /* trace_id */:
26427         field.get(&trace_id_);
26428         break;
26429       case 2 /* step */:
26430         field.get(&step_);
26431         break;
26432       case 3 /* frame_tree_node_id */:
26433         field.get(&frame_tree_node_id_);
26434         break;
26435       case 4 /* component_info */:
26436         component_info_.emplace_back();
26437         component_info_.back().ParseFromArray(field.data(), field.size());
26438         break;
26439       case 5 /* is_coalesced */:
26440         field.get(&is_coalesced_);
26441         break;
26442       case 6 /* gesture_scroll_id */:
26443         field.get(&gesture_scroll_id_);
26444         break;
26445       default:
26446         field.SerializeAndAppendTo(&unknown_fields_);
26447         break;
26448     }
26449   }
26450   return !packed_error && !dec.bytes_left();
26451 }
26452 
SerializeAsString() const26453 std::string ChromeLatencyInfo::SerializeAsString() const {
26454   ::protozero::HeapBuffered<::protozero::Message> msg;
26455   Serialize(msg.get());
26456   return msg.SerializeAsString();
26457 }
26458 
SerializeAsArray() const26459 std::vector<uint8_t> ChromeLatencyInfo::SerializeAsArray() const {
26460   ::protozero::HeapBuffered<::protozero::Message> msg;
26461   Serialize(msg.get());
26462   return msg.SerializeAsArray();
26463 }
26464 
Serialize(::protozero::Message * msg) const26465 void ChromeLatencyInfo::Serialize(::protozero::Message* msg) const {
26466   // Field 1: trace_id
26467   if (_has_field_[1]) {
26468     msg->AppendVarInt(1, trace_id_);
26469   }
26470 
26471   // Field 2: step
26472   if (_has_field_[2]) {
26473     msg->AppendVarInt(2, step_);
26474   }
26475 
26476   // Field 3: frame_tree_node_id
26477   if (_has_field_[3]) {
26478     msg->AppendVarInt(3, frame_tree_node_id_);
26479   }
26480 
26481   // Field 4: component_info
26482   for (auto& it : component_info_) {
26483     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
26484   }
26485 
26486   // Field 5: is_coalesced
26487   if (_has_field_[5]) {
26488     msg->AppendTinyVarInt(5, is_coalesced_);
26489   }
26490 
26491   // Field 6: gesture_scroll_id
26492   if (_has_field_[6]) {
26493     msg->AppendVarInt(6, gesture_scroll_id_);
26494   }
26495 
26496   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
26497 }
26498 
26499 
26500 ChromeLatencyInfo_ComponentInfo::ChromeLatencyInfo_ComponentInfo() = default;
26501 ChromeLatencyInfo_ComponentInfo::~ChromeLatencyInfo_ComponentInfo() = default;
26502 ChromeLatencyInfo_ComponentInfo::ChromeLatencyInfo_ComponentInfo(const ChromeLatencyInfo_ComponentInfo&) = default;
26503 ChromeLatencyInfo_ComponentInfo& ChromeLatencyInfo_ComponentInfo::operator=(const ChromeLatencyInfo_ComponentInfo&) = default;
26504 ChromeLatencyInfo_ComponentInfo::ChromeLatencyInfo_ComponentInfo(ChromeLatencyInfo_ComponentInfo&&) noexcept = default;
26505 ChromeLatencyInfo_ComponentInfo& ChromeLatencyInfo_ComponentInfo::operator=(ChromeLatencyInfo_ComponentInfo&&) = default;
26506 
operator ==(const ChromeLatencyInfo_ComponentInfo & other) const26507 bool ChromeLatencyInfo_ComponentInfo::operator==(const ChromeLatencyInfo_ComponentInfo& other) const {
26508   return unknown_fields_ == other.unknown_fields_
26509    && component_type_ == other.component_type_
26510    && time_us_ == other.time_us_;
26511 }
26512 
ParseFromArray(const void * raw,size_t size)26513 bool ChromeLatencyInfo_ComponentInfo::ParseFromArray(const void* raw, size_t size) {
26514   unknown_fields_.clear();
26515   bool packed_error = false;
26516 
26517   ::protozero::ProtoDecoder dec(raw, size);
26518   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
26519     if (field.id() < _has_field_.size()) {
26520       _has_field_.set(field.id());
26521     }
26522     switch (field.id()) {
26523       case 1 /* component_type */:
26524         field.get(&component_type_);
26525         break;
26526       case 2 /* time_us */:
26527         field.get(&time_us_);
26528         break;
26529       default:
26530         field.SerializeAndAppendTo(&unknown_fields_);
26531         break;
26532     }
26533   }
26534   return !packed_error && !dec.bytes_left();
26535 }
26536 
SerializeAsString() const26537 std::string ChromeLatencyInfo_ComponentInfo::SerializeAsString() const {
26538   ::protozero::HeapBuffered<::protozero::Message> msg;
26539   Serialize(msg.get());
26540   return msg.SerializeAsString();
26541 }
26542 
SerializeAsArray() const26543 std::vector<uint8_t> ChromeLatencyInfo_ComponentInfo::SerializeAsArray() const {
26544   ::protozero::HeapBuffered<::protozero::Message> msg;
26545   Serialize(msg.get());
26546   return msg.SerializeAsArray();
26547 }
26548 
Serialize(::protozero::Message * msg) const26549 void ChromeLatencyInfo_ComponentInfo::Serialize(::protozero::Message* msg) const {
26550   // Field 1: component_type
26551   if (_has_field_[1]) {
26552     msg->AppendVarInt(1, component_type_);
26553   }
26554 
26555   // Field 2: time_us
26556   if (_has_field_[2]) {
26557     msg->AppendVarInt(2, time_us_);
26558   }
26559 
26560   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
26561 }
26562 
26563 }  // namespace perfetto
26564 }  // namespace protos
26565 }  // namespace gen
26566 #if defined(__GNUC__) || defined(__clang__)
26567 #pragma GCC diagnostic pop
26568 #endif
26569 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_legacy_ipc.gen.cc
26570 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_legacy_ipc.gen.h
26571 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
26572 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LEGACY_IPC_PROTO_CPP_H_
26573 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LEGACY_IPC_PROTO_CPP_H_
26574 
26575 #include <stdint.h>
26576 #include <bitset>
26577 #include <vector>
26578 #include <string>
26579 #include <type_traits>
26580 
26581 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
26582 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
26583 // gen_amalgamated expanded: #include "perfetto/base/export.h"
26584 
26585 namespace perfetto {
26586 namespace protos {
26587 namespace gen {
26588 class ChromeLegacyIpc;
26589 enum ChromeLegacyIpc_MessageClass : int;
26590 }  // namespace perfetto
26591 }  // namespace protos
26592 }  // namespace gen
26593 
26594 namespace protozero {
26595 class Message;
26596 }  // namespace protozero
26597 
26598 namespace perfetto {
26599 namespace protos {
26600 namespace gen {
26601 enum ChromeLegacyIpc_MessageClass : int {
26602   ChromeLegacyIpc_MessageClass_CLASS_UNSPECIFIED = 0,
26603   ChromeLegacyIpc_MessageClass_CLASS_AUTOMATION = 1,
26604   ChromeLegacyIpc_MessageClass_CLASS_FRAME = 2,
26605   ChromeLegacyIpc_MessageClass_CLASS_PAGE = 3,
26606   ChromeLegacyIpc_MessageClass_CLASS_VIEW = 4,
26607   ChromeLegacyIpc_MessageClass_CLASS_WIDGET = 5,
26608   ChromeLegacyIpc_MessageClass_CLASS_INPUT = 6,
26609   ChromeLegacyIpc_MessageClass_CLASS_TEST = 7,
26610   ChromeLegacyIpc_MessageClass_CLASS_WORKER = 8,
26611   ChromeLegacyIpc_MessageClass_CLASS_NACL = 9,
26612   ChromeLegacyIpc_MessageClass_CLASS_GPU_CHANNEL = 10,
26613   ChromeLegacyIpc_MessageClass_CLASS_MEDIA = 11,
26614   ChromeLegacyIpc_MessageClass_CLASS_PPAPI = 12,
26615   ChromeLegacyIpc_MessageClass_CLASS_CHROME = 13,
26616   ChromeLegacyIpc_MessageClass_CLASS_DRAG = 14,
26617   ChromeLegacyIpc_MessageClass_CLASS_PRINT = 15,
26618   ChromeLegacyIpc_MessageClass_CLASS_EXTENSION = 16,
26619   ChromeLegacyIpc_MessageClass_CLASS_TEXT_INPUT_CLIENT = 17,
26620   ChromeLegacyIpc_MessageClass_CLASS_BLINK_TEST = 18,
26621   ChromeLegacyIpc_MessageClass_CLASS_ACCESSIBILITY = 19,
26622   ChromeLegacyIpc_MessageClass_CLASS_PRERENDER = 20,
26623   ChromeLegacyIpc_MessageClass_CLASS_CHROMOTING = 21,
26624   ChromeLegacyIpc_MessageClass_CLASS_BROWSER_PLUGIN = 22,
26625   ChromeLegacyIpc_MessageClass_CLASS_ANDROID_WEB_VIEW = 23,
26626   ChromeLegacyIpc_MessageClass_CLASS_NACL_HOST = 24,
26627   ChromeLegacyIpc_MessageClass_CLASS_ENCRYPTED_MEDIA = 25,
26628   ChromeLegacyIpc_MessageClass_CLASS_CAST = 26,
26629   ChromeLegacyIpc_MessageClass_CLASS_GIN_JAVA_BRIDGE = 27,
26630   ChromeLegacyIpc_MessageClass_CLASS_CHROME_UTILITY_PRINTING = 28,
26631   ChromeLegacyIpc_MessageClass_CLASS_OZONE_GPU = 29,
26632   ChromeLegacyIpc_MessageClass_CLASS_WEB_TEST = 30,
26633   ChromeLegacyIpc_MessageClass_CLASS_NETWORK_HINTS = 31,
26634   ChromeLegacyIpc_MessageClass_CLASS_EXTENSIONS_GUEST_VIEW = 32,
26635   ChromeLegacyIpc_MessageClass_CLASS_GUEST_VIEW = 33,
26636   ChromeLegacyIpc_MessageClass_CLASS_MEDIA_PLAYER_DELEGATE = 34,
26637   ChromeLegacyIpc_MessageClass_CLASS_EXTENSION_WORKER = 35,
26638   ChromeLegacyIpc_MessageClass_CLASS_SUBRESOURCE_FILTER = 36,
26639   ChromeLegacyIpc_MessageClass_CLASS_UNFREEZABLE_FRAME = 37,
26640 };
26641 
26642 class PERFETTO_EXPORT ChromeLegacyIpc : public ::protozero::CppMessageObj {
26643  public:
26644   using MessageClass = ChromeLegacyIpc_MessageClass;
26645   static constexpr auto CLASS_UNSPECIFIED = ChromeLegacyIpc_MessageClass_CLASS_UNSPECIFIED;
26646   static constexpr auto CLASS_AUTOMATION = ChromeLegacyIpc_MessageClass_CLASS_AUTOMATION;
26647   static constexpr auto CLASS_FRAME = ChromeLegacyIpc_MessageClass_CLASS_FRAME;
26648   static constexpr auto CLASS_PAGE = ChromeLegacyIpc_MessageClass_CLASS_PAGE;
26649   static constexpr auto CLASS_VIEW = ChromeLegacyIpc_MessageClass_CLASS_VIEW;
26650   static constexpr auto CLASS_WIDGET = ChromeLegacyIpc_MessageClass_CLASS_WIDGET;
26651   static constexpr auto CLASS_INPUT = ChromeLegacyIpc_MessageClass_CLASS_INPUT;
26652   static constexpr auto CLASS_TEST = ChromeLegacyIpc_MessageClass_CLASS_TEST;
26653   static constexpr auto CLASS_WORKER = ChromeLegacyIpc_MessageClass_CLASS_WORKER;
26654   static constexpr auto CLASS_NACL = ChromeLegacyIpc_MessageClass_CLASS_NACL;
26655   static constexpr auto CLASS_GPU_CHANNEL = ChromeLegacyIpc_MessageClass_CLASS_GPU_CHANNEL;
26656   static constexpr auto CLASS_MEDIA = ChromeLegacyIpc_MessageClass_CLASS_MEDIA;
26657   static constexpr auto CLASS_PPAPI = ChromeLegacyIpc_MessageClass_CLASS_PPAPI;
26658   static constexpr auto CLASS_CHROME = ChromeLegacyIpc_MessageClass_CLASS_CHROME;
26659   static constexpr auto CLASS_DRAG = ChromeLegacyIpc_MessageClass_CLASS_DRAG;
26660   static constexpr auto CLASS_PRINT = ChromeLegacyIpc_MessageClass_CLASS_PRINT;
26661   static constexpr auto CLASS_EXTENSION = ChromeLegacyIpc_MessageClass_CLASS_EXTENSION;
26662   static constexpr auto CLASS_TEXT_INPUT_CLIENT = ChromeLegacyIpc_MessageClass_CLASS_TEXT_INPUT_CLIENT;
26663   static constexpr auto CLASS_BLINK_TEST = ChromeLegacyIpc_MessageClass_CLASS_BLINK_TEST;
26664   static constexpr auto CLASS_ACCESSIBILITY = ChromeLegacyIpc_MessageClass_CLASS_ACCESSIBILITY;
26665   static constexpr auto CLASS_PRERENDER = ChromeLegacyIpc_MessageClass_CLASS_PRERENDER;
26666   static constexpr auto CLASS_CHROMOTING = ChromeLegacyIpc_MessageClass_CLASS_CHROMOTING;
26667   static constexpr auto CLASS_BROWSER_PLUGIN = ChromeLegacyIpc_MessageClass_CLASS_BROWSER_PLUGIN;
26668   static constexpr auto CLASS_ANDROID_WEB_VIEW = ChromeLegacyIpc_MessageClass_CLASS_ANDROID_WEB_VIEW;
26669   static constexpr auto CLASS_NACL_HOST = ChromeLegacyIpc_MessageClass_CLASS_NACL_HOST;
26670   static constexpr auto CLASS_ENCRYPTED_MEDIA = ChromeLegacyIpc_MessageClass_CLASS_ENCRYPTED_MEDIA;
26671   static constexpr auto CLASS_CAST = ChromeLegacyIpc_MessageClass_CLASS_CAST;
26672   static constexpr auto CLASS_GIN_JAVA_BRIDGE = ChromeLegacyIpc_MessageClass_CLASS_GIN_JAVA_BRIDGE;
26673   static constexpr auto CLASS_CHROME_UTILITY_PRINTING = ChromeLegacyIpc_MessageClass_CLASS_CHROME_UTILITY_PRINTING;
26674   static constexpr auto CLASS_OZONE_GPU = ChromeLegacyIpc_MessageClass_CLASS_OZONE_GPU;
26675   static constexpr auto CLASS_WEB_TEST = ChromeLegacyIpc_MessageClass_CLASS_WEB_TEST;
26676   static constexpr auto CLASS_NETWORK_HINTS = ChromeLegacyIpc_MessageClass_CLASS_NETWORK_HINTS;
26677   static constexpr auto CLASS_EXTENSIONS_GUEST_VIEW = ChromeLegacyIpc_MessageClass_CLASS_EXTENSIONS_GUEST_VIEW;
26678   static constexpr auto CLASS_GUEST_VIEW = ChromeLegacyIpc_MessageClass_CLASS_GUEST_VIEW;
26679   static constexpr auto CLASS_MEDIA_PLAYER_DELEGATE = ChromeLegacyIpc_MessageClass_CLASS_MEDIA_PLAYER_DELEGATE;
26680   static constexpr auto CLASS_EXTENSION_WORKER = ChromeLegacyIpc_MessageClass_CLASS_EXTENSION_WORKER;
26681   static constexpr auto CLASS_SUBRESOURCE_FILTER = ChromeLegacyIpc_MessageClass_CLASS_SUBRESOURCE_FILTER;
26682   static constexpr auto CLASS_UNFREEZABLE_FRAME = ChromeLegacyIpc_MessageClass_CLASS_UNFREEZABLE_FRAME;
26683   static constexpr auto MessageClass_MIN = ChromeLegacyIpc_MessageClass_CLASS_UNSPECIFIED;
26684   static constexpr auto MessageClass_MAX = ChromeLegacyIpc_MessageClass_CLASS_UNFREEZABLE_FRAME;
26685   enum FieldNumbers {
26686     kMessageClassFieldNumber = 1,
26687     kMessageLineFieldNumber = 2,
26688   };
26689 
26690   ChromeLegacyIpc();
26691   ~ChromeLegacyIpc() override;
26692   ChromeLegacyIpc(ChromeLegacyIpc&&) noexcept;
26693   ChromeLegacyIpc& operator=(ChromeLegacyIpc&&);
26694   ChromeLegacyIpc(const ChromeLegacyIpc&);
26695   ChromeLegacyIpc& operator=(const ChromeLegacyIpc&);
26696   bool operator==(const ChromeLegacyIpc&) const;
operator !=(const ChromeLegacyIpc & other) const26697   bool operator!=(const ChromeLegacyIpc& other) const { return !(*this == other); }
26698 
26699   bool ParseFromArray(const void*, size_t) override;
26700   std::string SerializeAsString() const override;
26701   std::vector<uint8_t> SerializeAsArray() const override;
26702   void Serialize(::protozero::Message*) const;
26703 
has_message_class() const26704   bool has_message_class() const { return _has_field_[1]; }
message_class() const26705   ChromeLegacyIpc_MessageClass message_class() const { return message_class_; }
set_message_class(ChromeLegacyIpc_MessageClass value)26706   void set_message_class(ChromeLegacyIpc_MessageClass value) { message_class_ = value; _has_field_.set(1); }
26707 
has_message_line() const26708   bool has_message_line() const { return _has_field_[2]; }
message_line() const26709   uint32_t message_line() const { return message_line_; }
set_message_line(uint32_t value)26710   void set_message_line(uint32_t value) { message_line_ = value; _has_field_.set(2); }
26711 
26712  private:
26713   ChromeLegacyIpc_MessageClass message_class_{};
26714   uint32_t message_line_{};
26715 
26716   // Allows to preserve unknown protobuf fields for compatibility
26717   // with future versions of .proto files.
26718   std::string unknown_fields_;
26719 
26720   std::bitset<3> _has_field_{};
26721 };
26722 
26723 }  // namespace perfetto
26724 }  // namespace protos
26725 }  // namespace gen
26726 
26727 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LEGACY_IPC_PROTO_CPP_H_
26728 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
26729 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
26730 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
26731 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
26732 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
26733 #if defined(__GNUC__) || defined(__clang__)
26734 #pragma GCC diagnostic push
26735 #pragma GCC diagnostic ignored "-Wfloat-equal"
26736 #endif
26737 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_legacy_ipc.gen.h"
26738 
26739 namespace perfetto {
26740 namespace protos {
26741 namespace gen {
26742 
26743 ChromeLegacyIpc::ChromeLegacyIpc() = default;
26744 ChromeLegacyIpc::~ChromeLegacyIpc() = default;
26745 ChromeLegacyIpc::ChromeLegacyIpc(const ChromeLegacyIpc&) = default;
26746 ChromeLegacyIpc& ChromeLegacyIpc::operator=(const ChromeLegacyIpc&) = default;
26747 ChromeLegacyIpc::ChromeLegacyIpc(ChromeLegacyIpc&&) noexcept = default;
26748 ChromeLegacyIpc& ChromeLegacyIpc::operator=(ChromeLegacyIpc&&) = default;
26749 
operator ==(const ChromeLegacyIpc & other) const26750 bool ChromeLegacyIpc::operator==(const ChromeLegacyIpc& other) const {
26751   return unknown_fields_ == other.unknown_fields_
26752    && message_class_ == other.message_class_
26753    && message_line_ == other.message_line_;
26754 }
26755 
ParseFromArray(const void * raw,size_t size)26756 bool ChromeLegacyIpc::ParseFromArray(const void* raw, size_t size) {
26757   unknown_fields_.clear();
26758   bool packed_error = false;
26759 
26760   ::protozero::ProtoDecoder dec(raw, size);
26761   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
26762     if (field.id() < _has_field_.size()) {
26763       _has_field_.set(field.id());
26764     }
26765     switch (field.id()) {
26766       case 1 /* message_class */:
26767         field.get(&message_class_);
26768         break;
26769       case 2 /* message_line */:
26770         field.get(&message_line_);
26771         break;
26772       default:
26773         field.SerializeAndAppendTo(&unknown_fields_);
26774         break;
26775     }
26776   }
26777   return !packed_error && !dec.bytes_left();
26778 }
26779 
SerializeAsString() const26780 std::string ChromeLegacyIpc::SerializeAsString() const {
26781   ::protozero::HeapBuffered<::protozero::Message> msg;
26782   Serialize(msg.get());
26783   return msg.SerializeAsString();
26784 }
26785 
SerializeAsArray() const26786 std::vector<uint8_t> ChromeLegacyIpc::SerializeAsArray() const {
26787   ::protozero::HeapBuffered<::protozero::Message> msg;
26788   Serialize(msg.get());
26789   return msg.SerializeAsArray();
26790 }
26791 
Serialize(::protozero::Message * msg) const26792 void ChromeLegacyIpc::Serialize(::protozero::Message* msg) const {
26793   // Field 1: message_class
26794   if (_has_field_[1]) {
26795     msg->AppendVarInt(1, message_class_);
26796   }
26797 
26798   // Field 2: message_line
26799   if (_has_field_[2]) {
26800     msg->AppendVarInt(2, message_line_);
26801   }
26802 
26803   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
26804 }
26805 
26806 }  // namespace perfetto
26807 }  // namespace protos
26808 }  // namespace gen
26809 #if defined(__GNUC__) || defined(__clang__)
26810 #pragma GCC diagnostic pop
26811 #endif
26812 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_message_pump.gen.cc
26813 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_message_pump.gen.h
26814 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
26815 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_MESSAGE_PUMP_PROTO_CPP_H_
26816 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_MESSAGE_PUMP_PROTO_CPP_H_
26817 
26818 #include <stdint.h>
26819 #include <bitset>
26820 #include <vector>
26821 #include <string>
26822 #include <type_traits>
26823 
26824 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
26825 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
26826 // gen_amalgamated expanded: #include "perfetto/base/export.h"
26827 
26828 namespace perfetto {
26829 namespace protos {
26830 namespace gen {
26831 class ChromeMessagePump;
26832 }  // namespace perfetto
26833 }  // namespace protos
26834 }  // namespace gen
26835 
26836 namespace protozero {
26837 class Message;
26838 }  // namespace protozero
26839 
26840 namespace perfetto {
26841 namespace protos {
26842 namespace gen {
26843 
26844 class PERFETTO_EXPORT ChromeMessagePump : public ::protozero::CppMessageObj {
26845  public:
26846   enum FieldNumbers {
26847     kSentMessagesInQueueFieldNumber = 1,
26848     kIoHandlerLocationIidFieldNumber = 2,
26849   };
26850 
26851   ChromeMessagePump();
26852   ~ChromeMessagePump() override;
26853   ChromeMessagePump(ChromeMessagePump&&) noexcept;
26854   ChromeMessagePump& operator=(ChromeMessagePump&&);
26855   ChromeMessagePump(const ChromeMessagePump&);
26856   ChromeMessagePump& operator=(const ChromeMessagePump&);
26857   bool operator==(const ChromeMessagePump&) const;
operator !=(const ChromeMessagePump & other) const26858   bool operator!=(const ChromeMessagePump& other) const { return !(*this == other); }
26859 
26860   bool ParseFromArray(const void*, size_t) override;
26861   std::string SerializeAsString() const override;
26862   std::vector<uint8_t> SerializeAsArray() const override;
26863   void Serialize(::protozero::Message*) const;
26864 
has_sent_messages_in_queue() const26865   bool has_sent_messages_in_queue() const { return _has_field_[1]; }
sent_messages_in_queue() const26866   bool sent_messages_in_queue() const { return sent_messages_in_queue_; }
set_sent_messages_in_queue(bool value)26867   void set_sent_messages_in_queue(bool value) { sent_messages_in_queue_ = value; _has_field_.set(1); }
26868 
has_io_handler_location_iid() const26869   bool has_io_handler_location_iid() const { return _has_field_[2]; }
io_handler_location_iid() const26870   uint64_t io_handler_location_iid() const { return io_handler_location_iid_; }
set_io_handler_location_iid(uint64_t value)26871   void set_io_handler_location_iid(uint64_t value) { io_handler_location_iid_ = value; _has_field_.set(2); }
26872 
26873  private:
26874   bool sent_messages_in_queue_{};
26875   uint64_t io_handler_location_iid_{};
26876 
26877   // Allows to preserve unknown protobuf fields for compatibility
26878   // with future versions of .proto files.
26879   std::string unknown_fields_;
26880 
26881   std::bitset<3> _has_field_{};
26882 };
26883 
26884 }  // namespace perfetto
26885 }  // namespace protos
26886 }  // namespace gen
26887 
26888 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_MESSAGE_PUMP_PROTO_CPP_H_
26889 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
26890 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
26891 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
26892 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
26893 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
26894 #if defined(__GNUC__) || defined(__clang__)
26895 #pragma GCC diagnostic push
26896 #pragma GCC diagnostic ignored "-Wfloat-equal"
26897 #endif
26898 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_message_pump.gen.h"
26899 
26900 namespace perfetto {
26901 namespace protos {
26902 namespace gen {
26903 
26904 ChromeMessagePump::ChromeMessagePump() = default;
26905 ChromeMessagePump::~ChromeMessagePump() = default;
26906 ChromeMessagePump::ChromeMessagePump(const ChromeMessagePump&) = default;
26907 ChromeMessagePump& ChromeMessagePump::operator=(const ChromeMessagePump&) = default;
26908 ChromeMessagePump::ChromeMessagePump(ChromeMessagePump&&) noexcept = default;
26909 ChromeMessagePump& ChromeMessagePump::operator=(ChromeMessagePump&&) = default;
26910 
operator ==(const ChromeMessagePump & other) const26911 bool ChromeMessagePump::operator==(const ChromeMessagePump& other) const {
26912   return unknown_fields_ == other.unknown_fields_
26913    && sent_messages_in_queue_ == other.sent_messages_in_queue_
26914    && io_handler_location_iid_ == other.io_handler_location_iid_;
26915 }
26916 
ParseFromArray(const void * raw,size_t size)26917 bool ChromeMessagePump::ParseFromArray(const void* raw, size_t size) {
26918   unknown_fields_.clear();
26919   bool packed_error = false;
26920 
26921   ::protozero::ProtoDecoder dec(raw, size);
26922   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
26923     if (field.id() < _has_field_.size()) {
26924       _has_field_.set(field.id());
26925     }
26926     switch (field.id()) {
26927       case 1 /* sent_messages_in_queue */:
26928         field.get(&sent_messages_in_queue_);
26929         break;
26930       case 2 /* io_handler_location_iid */:
26931         field.get(&io_handler_location_iid_);
26932         break;
26933       default:
26934         field.SerializeAndAppendTo(&unknown_fields_);
26935         break;
26936     }
26937   }
26938   return !packed_error && !dec.bytes_left();
26939 }
26940 
SerializeAsString() const26941 std::string ChromeMessagePump::SerializeAsString() const {
26942   ::protozero::HeapBuffered<::protozero::Message> msg;
26943   Serialize(msg.get());
26944   return msg.SerializeAsString();
26945 }
26946 
SerializeAsArray() const26947 std::vector<uint8_t> ChromeMessagePump::SerializeAsArray() const {
26948   ::protozero::HeapBuffered<::protozero::Message> msg;
26949   Serialize(msg.get());
26950   return msg.SerializeAsArray();
26951 }
26952 
Serialize(::protozero::Message * msg) const26953 void ChromeMessagePump::Serialize(::protozero::Message* msg) const {
26954   // Field 1: sent_messages_in_queue
26955   if (_has_field_[1]) {
26956     msg->AppendTinyVarInt(1, sent_messages_in_queue_);
26957   }
26958 
26959   // Field 2: io_handler_location_iid
26960   if (_has_field_[2]) {
26961     msg->AppendVarInt(2, io_handler_location_iid_);
26962   }
26963 
26964   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
26965 }
26966 
26967 }  // namespace perfetto
26968 }  // namespace protos
26969 }  // namespace gen
26970 #if defined(__GNUC__) || defined(__clang__)
26971 #pragma GCC diagnostic pop
26972 #endif
26973 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_mojo_event_info.gen.cc
26974 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_mojo_event_info.gen.h
26975 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
26976 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_MOJO_EVENT_INFO_PROTO_CPP_H_
26977 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_MOJO_EVENT_INFO_PROTO_CPP_H_
26978 
26979 #include <stdint.h>
26980 #include <bitset>
26981 #include <vector>
26982 #include <string>
26983 #include <type_traits>
26984 
26985 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
26986 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
26987 // gen_amalgamated expanded: #include "perfetto/base/export.h"
26988 
26989 namespace perfetto {
26990 namespace protos {
26991 namespace gen {
26992 class ChromeMojoEventInfo;
26993 }  // namespace perfetto
26994 }  // namespace protos
26995 }  // namespace gen
26996 
26997 namespace protozero {
26998 class Message;
26999 }  // namespace protozero
27000 
27001 namespace perfetto {
27002 namespace protos {
27003 namespace gen {
27004 
27005 class PERFETTO_EXPORT ChromeMojoEventInfo : public ::protozero::CppMessageObj {
27006  public:
27007   enum FieldNumbers {
27008     kWatcherNotifyInterfaceTagFieldNumber = 1,
27009     kIpcHashFieldNumber = 2,
27010     kMojoInterfaceTagFieldNumber = 3,
27011   };
27012 
27013   ChromeMojoEventInfo();
27014   ~ChromeMojoEventInfo() override;
27015   ChromeMojoEventInfo(ChromeMojoEventInfo&&) noexcept;
27016   ChromeMojoEventInfo& operator=(ChromeMojoEventInfo&&);
27017   ChromeMojoEventInfo(const ChromeMojoEventInfo&);
27018   ChromeMojoEventInfo& operator=(const ChromeMojoEventInfo&);
27019   bool operator==(const ChromeMojoEventInfo&) const;
operator !=(const ChromeMojoEventInfo & other) const27020   bool operator!=(const ChromeMojoEventInfo& other) const { return !(*this == other); }
27021 
27022   bool ParseFromArray(const void*, size_t) override;
27023   std::string SerializeAsString() const override;
27024   std::vector<uint8_t> SerializeAsArray() const override;
27025   void Serialize(::protozero::Message*) const;
27026 
has_watcher_notify_interface_tag() const27027   bool has_watcher_notify_interface_tag() const { return _has_field_[1]; }
watcher_notify_interface_tag() const27028   const std::string& watcher_notify_interface_tag() const { return watcher_notify_interface_tag_; }
set_watcher_notify_interface_tag(const std::string & value)27029   void set_watcher_notify_interface_tag(const std::string& value) { watcher_notify_interface_tag_ = value; _has_field_.set(1); }
27030 
has_ipc_hash() const27031   bool has_ipc_hash() const { return _has_field_[2]; }
ipc_hash() const27032   uint32_t ipc_hash() const { return ipc_hash_; }
set_ipc_hash(uint32_t value)27033   void set_ipc_hash(uint32_t value) { ipc_hash_ = value; _has_field_.set(2); }
27034 
has_mojo_interface_tag() const27035   bool has_mojo_interface_tag() const { return _has_field_[3]; }
mojo_interface_tag() const27036   const std::string& mojo_interface_tag() const { return mojo_interface_tag_; }
set_mojo_interface_tag(const std::string & value)27037   void set_mojo_interface_tag(const std::string& value) { mojo_interface_tag_ = value; _has_field_.set(3); }
27038 
27039  private:
27040   std::string watcher_notify_interface_tag_{};
27041   uint32_t ipc_hash_{};
27042   std::string mojo_interface_tag_{};
27043 
27044   // Allows to preserve unknown protobuf fields for compatibility
27045   // with future versions of .proto files.
27046   std::string unknown_fields_;
27047 
27048   std::bitset<4> _has_field_{};
27049 };
27050 
27051 }  // namespace perfetto
27052 }  // namespace protos
27053 }  // namespace gen
27054 
27055 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_MOJO_EVENT_INFO_PROTO_CPP_H_
27056 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
27057 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
27058 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
27059 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
27060 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
27061 #if defined(__GNUC__) || defined(__clang__)
27062 #pragma GCC diagnostic push
27063 #pragma GCC diagnostic ignored "-Wfloat-equal"
27064 #endif
27065 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_mojo_event_info.gen.h"
27066 
27067 namespace perfetto {
27068 namespace protos {
27069 namespace gen {
27070 
27071 ChromeMojoEventInfo::ChromeMojoEventInfo() = default;
27072 ChromeMojoEventInfo::~ChromeMojoEventInfo() = default;
27073 ChromeMojoEventInfo::ChromeMojoEventInfo(const ChromeMojoEventInfo&) = default;
27074 ChromeMojoEventInfo& ChromeMojoEventInfo::operator=(const ChromeMojoEventInfo&) = default;
27075 ChromeMojoEventInfo::ChromeMojoEventInfo(ChromeMojoEventInfo&&) noexcept = default;
27076 ChromeMojoEventInfo& ChromeMojoEventInfo::operator=(ChromeMojoEventInfo&&) = default;
27077 
operator ==(const ChromeMojoEventInfo & other) const27078 bool ChromeMojoEventInfo::operator==(const ChromeMojoEventInfo& other) const {
27079   return unknown_fields_ == other.unknown_fields_
27080    && watcher_notify_interface_tag_ == other.watcher_notify_interface_tag_
27081    && ipc_hash_ == other.ipc_hash_
27082    && mojo_interface_tag_ == other.mojo_interface_tag_;
27083 }
27084 
ParseFromArray(const void * raw,size_t size)27085 bool ChromeMojoEventInfo::ParseFromArray(const void* raw, size_t size) {
27086   unknown_fields_.clear();
27087   bool packed_error = false;
27088 
27089   ::protozero::ProtoDecoder dec(raw, size);
27090   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
27091     if (field.id() < _has_field_.size()) {
27092       _has_field_.set(field.id());
27093     }
27094     switch (field.id()) {
27095       case 1 /* watcher_notify_interface_tag */:
27096         field.get(&watcher_notify_interface_tag_);
27097         break;
27098       case 2 /* ipc_hash */:
27099         field.get(&ipc_hash_);
27100         break;
27101       case 3 /* mojo_interface_tag */:
27102         field.get(&mojo_interface_tag_);
27103         break;
27104       default:
27105         field.SerializeAndAppendTo(&unknown_fields_);
27106         break;
27107     }
27108   }
27109   return !packed_error && !dec.bytes_left();
27110 }
27111 
SerializeAsString() const27112 std::string ChromeMojoEventInfo::SerializeAsString() const {
27113   ::protozero::HeapBuffered<::protozero::Message> msg;
27114   Serialize(msg.get());
27115   return msg.SerializeAsString();
27116 }
27117 
SerializeAsArray() const27118 std::vector<uint8_t> ChromeMojoEventInfo::SerializeAsArray() const {
27119   ::protozero::HeapBuffered<::protozero::Message> msg;
27120   Serialize(msg.get());
27121   return msg.SerializeAsArray();
27122 }
27123 
Serialize(::protozero::Message * msg) const27124 void ChromeMojoEventInfo::Serialize(::protozero::Message* msg) const {
27125   // Field 1: watcher_notify_interface_tag
27126   if (_has_field_[1]) {
27127     msg->AppendString(1, watcher_notify_interface_tag_);
27128   }
27129 
27130   // Field 2: ipc_hash
27131   if (_has_field_[2]) {
27132     msg->AppendVarInt(2, ipc_hash_);
27133   }
27134 
27135   // Field 3: mojo_interface_tag
27136   if (_has_field_[3]) {
27137     msg->AppendString(3, mojo_interface_tag_);
27138   }
27139 
27140   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
27141 }
27142 
27143 }  // namespace perfetto
27144 }  // namespace protos
27145 }  // namespace gen
27146 #if defined(__GNUC__) || defined(__clang__)
27147 #pragma GCC diagnostic pop
27148 #endif
27149 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_process_descriptor.gen.cc
27150 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_process_descriptor.gen.h
27151 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
27152 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_PROCESS_DESCRIPTOR_PROTO_CPP_H_
27153 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_PROCESS_DESCRIPTOR_PROTO_CPP_H_
27154 
27155 #include <stdint.h>
27156 #include <bitset>
27157 #include <vector>
27158 #include <string>
27159 #include <type_traits>
27160 
27161 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
27162 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
27163 // gen_amalgamated expanded: #include "perfetto/base/export.h"
27164 
27165 namespace perfetto {
27166 namespace protos {
27167 namespace gen {
27168 class ChromeProcessDescriptor;
27169 enum ChromeProcessDescriptor_ProcessType : int;
27170 }  // namespace perfetto
27171 }  // namespace protos
27172 }  // namespace gen
27173 
27174 namespace protozero {
27175 class Message;
27176 }  // namespace protozero
27177 
27178 namespace perfetto {
27179 namespace protos {
27180 namespace gen {
27181 enum ChromeProcessDescriptor_ProcessType : int {
27182   ChromeProcessDescriptor_ProcessType_PROCESS_UNSPECIFIED = 0,
27183   ChromeProcessDescriptor_ProcessType_PROCESS_BROWSER = 1,
27184   ChromeProcessDescriptor_ProcessType_PROCESS_RENDERER = 2,
27185   ChromeProcessDescriptor_ProcessType_PROCESS_UTILITY = 3,
27186   ChromeProcessDescriptor_ProcessType_PROCESS_ZYGOTE = 4,
27187   ChromeProcessDescriptor_ProcessType_PROCESS_SANDBOX_HELPER = 5,
27188   ChromeProcessDescriptor_ProcessType_PROCESS_GPU = 6,
27189   ChromeProcessDescriptor_ProcessType_PROCESS_PPAPI_PLUGIN = 7,
27190   ChromeProcessDescriptor_ProcessType_PROCESS_PPAPI_BROKER = 8,
27191   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_NETWORK = 9,
27192   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_TRACING = 10,
27193   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_STORAGE = 11,
27194   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_AUDIO = 12,
27195   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_DATA_DECODER = 13,
27196   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_UTIL_WIN = 14,
27197   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PROXY_RESOLVER = 15,
27198   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_CDM = 16,
27199   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_VIDEO_CAPTURE = 17,
27200   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_UNZIPPER = 18,
27201   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_MIRRORING = 19,
27202   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_FILEPATCHER = 20,
27203   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_TTS = 21,
27204   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PRINTING = 22,
27205   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_QUARANTINE = 23,
27206   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_CROS_LOCALSEARCH = 24,
27207   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_CROS_ASSISTANT_AUDIO_DECODER = 25,
27208   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_FILEUTIL = 26,
27209   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PRINTCOMPOSITOR = 27,
27210   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PAINTPREVIEW = 28,
27211   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_SPEECHRECOGNITION = 29,
27212   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_XRDEVICE = 30,
27213   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_READICON = 31,
27214   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_LANGUAGEDETECTION = 32,
27215   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_SHARING = 33,
27216   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_MEDIAPARSER = 34,
27217   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_QRCODEGENERATOR = 35,
27218   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PROFILEIMPORT = 36,
27219   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_IME = 37,
27220   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_RECORDING = 38,
27221   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_SHAPEDETECTION = 39,
27222 };
27223 
27224 class PERFETTO_EXPORT ChromeProcessDescriptor : public ::protozero::CppMessageObj {
27225  public:
27226   using ProcessType = ChromeProcessDescriptor_ProcessType;
27227   static constexpr auto PROCESS_UNSPECIFIED = ChromeProcessDescriptor_ProcessType_PROCESS_UNSPECIFIED;
27228   static constexpr auto PROCESS_BROWSER = ChromeProcessDescriptor_ProcessType_PROCESS_BROWSER;
27229   static constexpr auto PROCESS_RENDERER = ChromeProcessDescriptor_ProcessType_PROCESS_RENDERER;
27230   static constexpr auto PROCESS_UTILITY = ChromeProcessDescriptor_ProcessType_PROCESS_UTILITY;
27231   static constexpr auto PROCESS_ZYGOTE = ChromeProcessDescriptor_ProcessType_PROCESS_ZYGOTE;
27232   static constexpr auto PROCESS_SANDBOX_HELPER = ChromeProcessDescriptor_ProcessType_PROCESS_SANDBOX_HELPER;
27233   static constexpr auto PROCESS_GPU = ChromeProcessDescriptor_ProcessType_PROCESS_GPU;
27234   static constexpr auto PROCESS_PPAPI_PLUGIN = ChromeProcessDescriptor_ProcessType_PROCESS_PPAPI_PLUGIN;
27235   static constexpr auto PROCESS_PPAPI_BROKER = ChromeProcessDescriptor_ProcessType_PROCESS_PPAPI_BROKER;
27236   static constexpr auto PROCESS_SERVICE_NETWORK = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_NETWORK;
27237   static constexpr auto PROCESS_SERVICE_TRACING = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_TRACING;
27238   static constexpr auto PROCESS_SERVICE_STORAGE = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_STORAGE;
27239   static constexpr auto PROCESS_SERVICE_AUDIO = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_AUDIO;
27240   static constexpr auto PROCESS_SERVICE_DATA_DECODER = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_DATA_DECODER;
27241   static constexpr auto PROCESS_SERVICE_UTIL_WIN = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_UTIL_WIN;
27242   static constexpr auto PROCESS_SERVICE_PROXY_RESOLVER = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PROXY_RESOLVER;
27243   static constexpr auto PROCESS_SERVICE_CDM = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_CDM;
27244   static constexpr auto PROCESS_SERVICE_VIDEO_CAPTURE = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_VIDEO_CAPTURE;
27245   static constexpr auto PROCESS_SERVICE_UNZIPPER = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_UNZIPPER;
27246   static constexpr auto PROCESS_SERVICE_MIRRORING = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_MIRRORING;
27247   static constexpr auto PROCESS_SERVICE_FILEPATCHER = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_FILEPATCHER;
27248   static constexpr auto PROCESS_SERVICE_TTS = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_TTS;
27249   static constexpr auto PROCESS_SERVICE_PRINTING = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PRINTING;
27250   static constexpr auto PROCESS_SERVICE_QUARANTINE = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_QUARANTINE;
27251   static constexpr auto PROCESS_SERVICE_CROS_LOCALSEARCH = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_CROS_LOCALSEARCH;
27252   static constexpr auto PROCESS_SERVICE_CROS_ASSISTANT_AUDIO_DECODER = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_CROS_ASSISTANT_AUDIO_DECODER;
27253   static constexpr auto PROCESS_SERVICE_FILEUTIL = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_FILEUTIL;
27254   static constexpr auto PROCESS_SERVICE_PRINTCOMPOSITOR = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PRINTCOMPOSITOR;
27255   static constexpr auto PROCESS_SERVICE_PAINTPREVIEW = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PAINTPREVIEW;
27256   static constexpr auto PROCESS_SERVICE_SPEECHRECOGNITION = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_SPEECHRECOGNITION;
27257   static constexpr auto PROCESS_SERVICE_XRDEVICE = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_XRDEVICE;
27258   static constexpr auto PROCESS_SERVICE_READICON = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_READICON;
27259   static constexpr auto PROCESS_SERVICE_LANGUAGEDETECTION = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_LANGUAGEDETECTION;
27260   static constexpr auto PROCESS_SERVICE_SHARING = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_SHARING;
27261   static constexpr auto PROCESS_SERVICE_MEDIAPARSER = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_MEDIAPARSER;
27262   static constexpr auto PROCESS_SERVICE_QRCODEGENERATOR = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_QRCODEGENERATOR;
27263   static constexpr auto PROCESS_SERVICE_PROFILEIMPORT = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PROFILEIMPORT;
27264   static constexpr auto PROCESS_SERVICE_IME = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_IME;
27265   static constexpr auto PROCESS_SERVICE_RECORDING = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_RECORDING;
27266   static constexpr auto PROCESS_SERVICE_SHAPEDETECTION = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_SHAPEDETECTION;
27267   static constexpr auto ProcessType_MIN = ChromeProcessDescriptor_ProcessType_PROCESS_UNSPECIFIED;
27268   static constexpr auto ProcessType_MAX = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_SHAPEDETECTION;
27269   enum FieldNumbers {
27270     kProcessTypeFieldNumber = 1,
27271     kProcessPriorityFieldNumber = 2,
27272     kLegacySortIndexFieldNumber = 3,
27273     kHostAppPackageNameFieldNumber = 4,
27274     kCrashTraceIdFieldNumber = 5,
27275   };
27276 
27277   ChromeProcessDescriptor();
27278   ~ChromeProcessDescriptor() override;
27279   ChromeProcessDescriptor(ChromeProcessDescriptor&&) noexcept;
27280   ChromeProcessDescriptor& operator=(ChromeProcessDescriptor&&);
27281   ChromeProcessDescriptor(const ChromeProcessDescriptor&);
27282   ChromeProcessDescriptor& operator=(const ChromeProcessDescriptor&);
27283   bool operator==(const ChromeProcessDescriptor&) const;
operator !=(const ChromeProcessDescriptor & other) const27284   bool operator!=(const ChromeProcessDescriptor& other) const { return !(*this == other); }
27285 
27286   bool ParseFromArray(const void*, size_t) override;
27287   std::string SerializeAsString() const override;
27288   std::vector<uint8_t> SerializeAsArray() const override;
27289   void Serialize(::protozero::Message*) const;
27290 
has_process_type() const27291   bool has_process_type() const { return _has_field_[1]; }
process_type() const27292   ChromeProcessDescriptor_ProcessType process_type() const { return process_type_; }
set_process_type(ChromeProcessDescriptor_ProcessType value)27293   void set_process_type(ChromeProcessDescriptor_ProcessType value) { process_type_ = value; _has_field_.set(1); }
27294 
has_process_priority() const27295   bool has_process_priority() const { return _has_field_[2]; }
process_priority() const27296   int32_t process_priority() const { return process_priority_; }
set_process_priority(int32_t value)27297   void set_process_priority(int32_t value) { process_priority_ = value; _has_field_.set(2); }
27298 
has_legacy_sort_index() const27299   bool has_legacy_sort_index() const { return _has_field_[3]; }
legacy_sort_index() const27300   int32_t legacy_sort_index() const { return legacy_sort_index_; }
set_legacy_sort_index(int32_t value)27301   void set_legacy_sort_index(int32_t value) { legacy_sort_index_ = value; _has_field_.set(3); }
27302 
has_host_app_package_name() const27303   bool has_host_app_package_name() const { return _has_field_[4]; }
host_app_package_name() const27304   const std::string& host_app_package_name() const { return host_app_package_name_; }
set_host_app_package_name(const std::string & value)27305   void set_host_app_package_name(const std::string& value) { host_app_package_name_ = value; _has_field_.set(4); }
27306 
has_crash_trace_id() const27307   bool has_crash_trace_id() const { return _has_field_[5]; }
crash_trace_id() const27308   uint64_t crash_trace_id() const { return crash_trace_id_; }
set_crash_trace_id(uint64_t value)27309   void set_crash_trace_id(uint64_t value) { crash_trace_id_ = value; _has_field_.set(5); }
27310 
27311  private:
27312   ChromeProcessDescriptor_ProcessType process_type_{};
27313   int32_t process_priority_{};
27314   int32_t legacy_sort_index_{};
27315   std::string host_app_package_name_{};
27316   uint64_t crash_trace_id_{};
27317 
27318   // Allows to preserve unknown protobuf fields for compatibility
27319   // with future versions of .proto files.
27320   std::string unknown_fields_;
27321 
27322   std::bitset<6> _has_field_{};
27323 };
27324 
27325 }  // namespace perfetto
27326 }  // namespace protos
27327 }  // namespace gen
27328 
27329 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_PROCESS_DESCRIPTOR_PROTO_CPP_H_
27330 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
27331 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
27332 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
27333 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
27334 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
27335 #if defined(__GNUC__) || defined(__clang__)
27336 #pragma GCC diagnostic push
27337 #pragma GCC diagnostic ignored "-Wfloat-equal"
27338 #endif
27339 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_process_descriptor.gen.h"
27340 
27341 namespace perfetto {
27342 namespace protos {
27343 namespace gen {
27344 
27345 ChromeProcessDescriptor::ChromeProcessDescriptor() = default;
27346 ChromeProcessDescriptor::~ChromeProcessDescriptor() = default;
27347 ChromeProcessDescriptor::ChromeProcessDescriptor(const ChromeProcessDescriptor&) = default;
27348 ChromeProcessDescriptor& ChromeProcessDescriptor::operator=(const ChromeProcessDescriptor&) = default;
27349 ChromeProcessDescriptor::ChromeProcessDescriptor(ChromeProcessDescriptor&&) noexcept = default;
27350 ChromeProcessDescriptor& ChromeProcessDescriptor::operator=(ChromeProcessDescriptor&&) = default;
27351 
operator ==(const ChromeProcessDescriptor & other) const27352 bool ChromeProcessDescriptor::operator==(const ChromeProcessDescriptor& other) const {
27353   return unknown_fields_ == other.unknown_fields_
27354    && process_type_ == other.process_type_
27355    && process_priority_ == other.process_priority_
27356    && legacy_sort_index_ == other.legacy_sort_index_
27357    && host_app_package_name_ == other.host_app_package_name_
27358    && crash_trace_id_ == other.crash_trace_id_;
27359 }
27360 
ParseFromArray(const void * raw,size_t size)27361 bool ChromeProcessDescriptor::ParseFromArray(const void* raw, size_t size) {
27362   unknown_fields_.clear();
27363   bool packed_error = false;
27364 
27365   ::protozero::ProtoDecoder dec(raw, size);
27366   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
27367     if (field.id() < _has_field_.size()) {
27368       _has_field_.set(field.id());
27369     }
27370     switch (field.id()) {
27371       case 1 /* process_type */:
27372         field.get(&process_type_);
27373         break;
27374       case 2 /* process_priority */:
27375         field.get(&process_priority_);
27376         break;
27377       case 3 /* legacy_sort_index */:
27378         field.get(&legacy_sort_index_);
27379         break;
27380       case 4 /* host_app_package_name */:
27381         field.get(&host_app_package_name_);
27382         break;
27383       case 5 /* crash_trace_id */:
27384         field.get(&crash_trace_id_);
27385         break;
27386       default:
27387         field.SerializeAndAppendTo(&unknown_fields_);
27388         break;
27389     }
27390   }
27391   return !packed_error && !dec.bytes_left();
27392 }
27393 
SerializeAsString() const27394 std::string ChromeProcessDescriptor::SerializeAsString() const {
27395   ::protozero::HeapBuffered<::protozero::Message> msg;
27396   Serialize(msg.get());
27397   return msg.SerializeAsString();
27398 }
27399 
SerializeAsArray() const27400 std::vector<uint8_t> ChromeProcessDescriptor::SerializeAsArray() const {
27401   ::protozero::HeapBuffered<::protozero::Message> msg;
27402   Serialize(msg.get());
27403   return msg.SerializeAsArray();
27404 }
27405 
Serialize(::protozero::Message * msg) const27406 void ChromeProcessDescriptor::Serialize(::protozero::Message* msg) const {
27407   // Field 1: process_type
27408   if (_has_field_[1]) {
27409     msg->AppendVarInt(1, process_type_);
27410   }
27411 
27412   // Field 2: process_priority
27413   if (_has_field_[2]) {
27414     msg->AppendVarInt(2, process_priority_);
27415   }
27416 
27417   // Field 3: legacy_sort_index
27418   if (_has_field_[3]) {
27419     msg->AppendVarInt(3, legacy_sort_index_);
27420   }
27421 
27422   // Field 4: host_app_package_name
27423   if (_has_field_[4]) {
27424     msg->AppendString(4, host_app_package_name_);
27425   }
27426 
27427   // Field 5: crash_trace_id
27428   if (_has_field_[5]) {
27429     msg->AppendVarInt(5, crash_trace_id_);
27430   }
27431 
27432   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
27433 }
27434 
27435 }  // namespace perfetto
27436 }  // namespace protos
27437 }  // namespace gen
27438 #if defined(__GNUC__) || defined(__clang__)
27439 #pragma GCC diagnostic pop
27440 #endif
27441 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.gen.cc
27442 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.gen.h
27443 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
27444 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_RENDERER_SCHEDULER_STATE_PROTO_CPP_H_
27445 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_RENDERER_SCHEDULER_STATE_PROTO_CPP_H_
27446 
27447 #include <stdint.h>
27448 #include <bitset>
27449 #include <vector>
27450 #include <string>
27451 #include <type_traits>
27452 
27453 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
27454 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
27455 // gen_amalgamated expanded: #include "perfetto/base/export.h"
27456 
27457 namespace perfetto {
27458 namespace protos {
27459 namespace gen {
27460 class ChromeRendererSchedulerState;
27461 enum ChromeRAILMode : int;
27462 }  // namespace perfetto
27463 }  // namespace protos
27464 }  // namespace gen
27465 
27466 namespace protozero {
27467 class Message;
27468 }  // namespace protozero
27469 
27470 namespace perfetto {
27471 namespace protos {
27472 namespace gen {
27473 enum ChromeRAILMode : int {
27474   RAIL_MODE_NONE = 0,
27475   RAIL_MODE_RESPONSE = 1,
27476   RAIL_MODE_ANIMATION = 2,
27477   RAIL_MODE_IDLE = 3,
27478   RAIL_MODE_LOAD = 4,
27479 };
27480 
27481 class PERFETTO_EXPORT ChromeRendererSchedulerState : public ::protozero::CppMessageObj {
27482  public:
27483   enum FieldNumbers {
27484     kRailModeFieldNumber = 1,
27485   };
27486 
27487   ChromeRendererSchedulerState();
27488   ~ChromeRendererSchedulerState() override;
27489   ChromeRendererSchedulerState(ChromeRendererSchedulerState&&) noexcept;
27490   ChromeRendererSchedulerState& operator=(ChromeRendererSchedulerState&&);
27491   ChromeRendererSchedulerState(const ChromeRendererSchedulerState&);
27492   ChromeRendererSchedulerState& operator=(const ChromeRendererSchedulerState&);
27493   bool operator==(const ChromeRendererSchedulerState&) const;
operator !=(const ChromeRendererSchedulerState & other) const27494   bool operator!=(const ChromeRendererSchedulerState& other) const { return !(*this == other); }
27495 
27496   bool ParseFromArray(const void*, size_t) override;
27497   std::string SerializeAsString() const override;
27498   std::vector<uint8_t> SerializeAsArray() const override;
27499   void Serialize(::protozero::Message*) const;
27500 
has_rail_mode() const27501   bool has_rail_mode() const { return _has_field_[1]; }
rail_mode() const27502   ChromeRAILMode rail_mode() const { return rail_mode_; }
set_rail_mode(ChromeRAILMode value)27503   void set_rail_mode(ChromeRAILMode value) { rail_mode_ = value; _has_field_.set(1); }
27504 
27505  private:
27506   ChromeRAILMode rail_mode_{};
27507 
27508   // Allows to preserve unknown protobuf fields for compatibility
27509   // with future versions of .proto files.
27510   std::string unknown_fields_;
27511 
27512   std::bitset<2> _has_field_{};
27513 };
27514 
27515 }  // namespace perfetto
27516 }  // namespace protos
27517 }  // namespace gen
27518 
27519 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_RENDERER_SCHEDULER_STATE_PROTO_CPP_H_
27520 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
27521 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
27522 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
27523 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
27524 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
27525 #if defined(__GNUC__) || defined(__clang__)
27526 #pragma GCC diagnostic push
27527 #pragma GCC diagnostic ignored "-Wfloat-equal"
27528 #endif
27529 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.gen.h"
27530 
27531 namespace perfetto {
27532 namespace protos {
27533 namespace gen {
27534 
27535 ChromeRendererSchedulerState::ChromeRendererSchedulerState() = default;
27536 ChromeRendererSchedulerState::~ChromeRendererSchedulerState() = default;
27537 ChromeRendererSchedulerState::ChromeRendererSchedulerState(const ChromeRendererSchedulerState&) = default;
27538 ChromeRendererSchedulerState& ChromeRendererSchedulerState::operator=(const ChromeRendererSchedulerState&) = default;
27539 ChromeRendererSchedulerState::ChromeRendererSchedulerState(ChromeRendererSchedulerState&&) noexcept = default;
27540 ChromeRendererSchedulerState& ChromeRendererSchedulerState::operator=(ChromeRendererSchedulerState&&) = default;
27541 
operator ==(const ChromeRendererSchedulerState & other) const27542 bool ChromeRendererSchedulerState::operator==(const ChromeRendererSchedulerState& other) const {
27543   return unknown_fields_ == other.unknown_fields_
27544    && rail_mode_ == other.rail_mode_;
27545 }
27546 
ParseFromArray(const void * raw,size_t size)27547 bool ChromeRendererSchedulerState::ParseFromArray(const void* raw, size_t size) {
27548   unknown_fields_.clear();
27549   bool packed_error = false;
27550 
27551   ::protozero::ProtoDecoder dec(raw, size);
27552   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
27553     if (field.id() < _has_field_.size()) {
27554       _has_field_.set(field.id());
27555     }
27556     switch (field.id()) {
27557       case 1 /* rail_mode */:
27558         field.get(&rail_mode_);
27559         break;
27560       default:
27561         field.SerializeAndAppendTo(&unknown_fields_);
27562         break;
27563     }
27564   }
27565   return !packed_error && !dec.bytes_left();
27566 }
27567 
SerializeAsString() const27568 std::string ChromeRendererSchedulerState::SerializeAsString() const {
27569   ::protozero::HeapBuffered<::protozero::Message> msg;
27570   Serialize(msg.get());
27571   return msg.SerializeAsString();
27572 }
27573 
SerializeAsArray() const27574 std::vector<uint8_t> ChromeRendererSchedulerState::SerializeAsArray() const {
27575   ::protozero::HeapBuffered<::protozero::Message> msg;
27576   Serialize(msg.get());
27577   return msg.SerializeAsArray();
27578 }
27579 
Serialize(::protozero::Message * msg) const27580 void ChromeRendererSchedulerState::Serialize(::protozero::Message* msg) const {
27581   // Field 1: rail_mode
27582   if (_has_field_[1]) {
27583     msg->AppendVarInt(1, rail_mode_);
27584   }
27585 
27586   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
27587 }
27588 
27589 }  // namespace perfetto
27590 }  // namespace protos
27591 }  // namespace gen
27592 #if defined(__GNUC__) || defined(__clang__)
27593 #pragma GCC diagnostic pop
27594 #endif
27595 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_thread_descriptor.gen.cc
27596 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_thread_descriptor.gen.h
27597 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
27598 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_THREAD_DESCRIPTOR_PROTO_CPP_H_
27599 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_THREAD_DESCRIPTOR_PROTO_CPP_H_
27600 
27601 #include <stdint.h>
27602 #include <bitset>
27603 #include <vector>
27604 #include <string>
27605 #include <type_traits>
27606 
27607 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
27608 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
27609 // gen_amalgamated expanded: #include "perfetto/base/export.h"
27610 
27611 namespace perfetto {
27612 namespace protos {
27613 namespace gen {
27614 class ChromeThreadDescriptor;
27615 enum ChromeThreadDescriptor_ThreadType : int;
27616 }  // namespace perfetto
27617 }  // namespace protos
27618 }  // namespace gen
27619 
27620 namespace protozero {
27621 class Message;
27622 }  // namespace protozero
27623 
27624 namespace perfetto {
27625 namespace protos {
27626 namespace gen {
27627 enum ChromeThreadDescriptor_ThreadType : int {
27628   ChromeThreadDescriptor_ThreadType_THREAD_UNSPECIFIED = 0,
27629   ChromeThreadDescriptor_ThreadType_THREAD_MAIN = 1,
27630   ChromeThreadDescriptor_ThreadType_THREAD_IO = 2,
27631   ChromeThreadDescriptor_ThreadType_THREAD_POOL_BG_WORKER = 3,
27632   ChromeThreadDescriptor_ThreadType_THREAD_POOL_FG_WORKER = 4,
27633   ChromeThreadDescriptor_ThreadType_THREAD_POOL_FG_BLOCKING = 5,
27634   ChromeThreadDescriptor_ThreadType_THREAD_POOL_BG_BLOCKING = 6,
27635   ChromeThreadDescriptor_ThreadType_THREAD_POOL_SERVICE = 7,
27636   ChromeThreadDescriptor_ThreadType_THREAD_COMPOSITOR = 8,
27637   ChromeThreadDescriptor_ThreadType_THREAD_VIZ_COMPOSITOR = 9,
27638   ChromeThreadDescriptor_ThreadType_THREAD_COMPOSITOR_WORKER = 10,
27639   ChromeThreadDescriptor_ThreadType_THREAD_SERVICE_WORKER = 11,
27640   ChromeThreadDescriptor_ThreadType_THREAD_NETWORK_SERVICE = 12,
27641   ChromeThreadDescriptor_ThreadType_THREAD_CHILD_IO = 13,
27642   ChromeThreadDescriptor_ThreadType_THREAD_BROWSER_IO = 14,
27643   ChromeThreadDescriptor_ThreadType_THREAD_BROWSER_MAIN = 15,
27644   ChromeThreadDescriptor_ThreadType_THREAD_RENDERER_MAIN = 16,
27645   ChromeThreadDescriptor_ThreadType_THREAD_UTILITY_MAIN = 17,
27646   ChromeThreadDescriptor_ThreadType_THREAD_GPU_MAIN = 18,
27647   ChromeThreadDescriptor_ThreadType_THREAD_CACHE_BLOCKFILE = 19,
27648   ChromeThreadDescriptor_ThreadType_THREAD_MEDIA = 20,
27649   ChromeThreadDescriptor_ThreadType_THREAD_AUDIO_OUTPUTDEVICE = 21,
27650   ChromeThreadDescriptor_ThreadType_THREAD_AUDIO_INPUTDEVICE = 22,
27651   ChromeThreadDescriptor_ThreadType_THREAD_GPU_MEMORY = 23,
27652   ChromeThreadDescriptor_ThreadType_THREAD_GPU_VSYNC = 24,
27653   ChromeThreadDescriptor_ThreadType_THREAD_DXA_VIDEODECODER = 25,
27654   ChromeThreadDescriptor_ThreadType_THREAD_BROWSER_WATCHDOG = 26,
27655   ChromeThreadDescriptor_ThreadType_THREAD_WEBRTC_NETWORK = 27,
27656   ChromeThreadDescriptor_ThreadType_THREAD_WINDOW_OWNER = 28,
27657   ChromeThreadDescriptor_ThreadType_THREAD_WEBRTC_SIGNALING = 29,
27658   ChromeThreadDescriptor_ThreadType_THREAD_WEBRTC_WORKER = 30,
27659   ChromeThreadDescriptor_ThreadType_THREAD_PPAPI_MAIN = 31,
27660   ChromeThreadDescriptor_ThreadType_THREAD_GPU_WATCHDOG = 32,
27661   ChromeThreadDescriptor_ThreadType_THREAD_SWAPPER = 33,
27662   ChromeThreadDescriptor_ThreadType_THREAD_GAMEPAD_POLLING = 34,
27663   ChromeThreadDescriptor_ThreadType_THREAD_WEBCRYPTO = 35,
27664   ChromeThreadDescriptor_ThreadType_THREAD_DATABASE = 36,
27665   ChromeThreadDescriptor_ThreadType_THREAD_PROXYRESOLVER = 37,
27666   ChromeThreadDescriptor_ThreadType_THREAD_DEVTOOLSADB = 38,
27667   ChromeThreadDescriptor_ThreadType_THREAD_NETWORKCONFIGWATCHER = 39,
27668   ChromeThreadDescriptor_ThreadType_THREAD_WASAPI_RENDER = 40,
27669   ChromeThreadDescriptor_ThreadType_THREAD_MEMORY_INFRA = 50,
27670   ChromeThreadDescriptor_ThreadType_THREAD_SAMPLING_PROFILER = 51,
27671 };
27672 
27673 class PERFETTO_EXPORT ChromeThreadDescriptor : public ::protozero::CppMessageObj {
27674  public:
27675   using ThreadType = ChromeThreadDescriptor_ThreadType;
27676   static constexpr auto THREAD_UNSPECIFIED = ChromeThreadDescriptor_ThreadType_THREAD_UNSPECIFIED;
27677   static constexpr auto THREAD_MAIN = ChromeThreadDescriptor_ThreadType_THREAD_MAIN;
27678   static constexpr auto THREAD_IO = ChromeThreadDescriptor_ThreadType_THREAD_IO;
27679   static constexpr auto THREAD_POOL_BG_WORKER = ChromeThreadDescriptor_ThreadType_THREAD_POOL_BG_WORKER;
27680   static constexpr auto THREAD_POOL_FG_WORKER = ChromeThreadDescriptor_ThreadType_THREAD_POOL_FG_WORKER;
27681   static constexpr auto THREAD_POOL_FG_BLOCKING = ChromeThreadDescriptor_ThreadType_THREAD_POOL_FG_BLOCKING;
27682   static constexpr auto THREAD_POOL_BG_BLOCKING = ChromeThreadDescriptor_ThreadType_THREAD_POOL_BG_BLOCKING;
27683   static constexpr auto THREAD_POOL_SERVICE = ChromeThreadDescriptor_ThreadType_THREAD_POOL_SERVICE;
27684   static constexpr auto THREAD_COMPOSITOR = ChromeThreadDescriptor_ThreadType_THREAD_COMPOSITOR;
27685   static constexpr auto THREAD_VIZ_COMPOSITOR = ChromeThreadDescriptor_ThreadType_THREAD_VIZ_COMPOSITOR;
27686   static constexpr auto THREAD_COMPOSITOR_WORKER = ChromeThreadDescriptor_ThreadType_THREAD_COMPOSITOR_WORKER;
27687   static constexpr auto THREAD_SERVICE_WORKER = ChromeThreadDescriptor_ThreadType_THREAD_SERVICE_WORKER;
27688   static constexpr auto THREAD_NETWORK_SERVICE = ChromeThreadDescriptor_ThreadType_THREAD_NETWORK_SERVICE;
27689   static constexpr auto THREAD_CHILD_IO = ChromeThreadDescriptor_ThreadType_THREAD_CHILD_IO;
27690   static constexpr auto THREAD_BROWSER_IO = ChromeThreadDescriptor_ThreadType_THREAD_BROWSER_IO;
27691   static constexpr auto THREAD_BROWSER_MAIN = ChromeThreadDescriptor_ThreadType_THREAD_BROWSER_MAIN;
27692   static constexpr auto THREAD_RENDERER_MAIN = ChromeThreadDescriptor_ThreadType_THREAD_RENDERER_MAIN;
27693   static constexpr auto THREAD_UTILITY_MAIN = ChromeThreadDescriptor_ThreadType_THREAD_UTILITY_MAIN;
27694   static constexpr auto THREAD_GPU_MAIN = ChromeThreadDescriptor_ThreadType_THREAD_GPU_MAIN;
27695   static constexpr auto THREAD_CACHE_BLOCKFILE = ChromeThreadDescriptor_ThreadType_THREAD_CACHE_BLOCKFILE;
27696   static constexpr auto THREAD_MEDIA = ChromeThreadDescriptor_ThreadType_THREAD_MEDIA;
27697   static constexpr auto THREAD_AUDIO_OUTPUTDEVICE = ChromeThreadDescriptor_ThreadType_THREAD_AUDIO_OUTPUTDEVICE;
27698   static constexpr auto THREAD_AUDIO_INPUTDEVICE = ChromeThreadDescriptor_ThreadType_THREAD_AUDIO_INPUTDEVICE;
27699   static constexpr auto THREAD_GPU_MEMORY = ChromeThreadDescriptor_ThreadType_THREAD_GPU_MEMORY;
27700   static constexpr auto THREAD_GPU_VSYNC = ChromeThreadDescriptor_ThreadType_THREAD_GPU_VSYNC;
27701   static constexpr auto THREAD_DXA_VIDEODECODER = ChromeThreadDescriptor_ThreadType_THREAD_DXA_VIDEODECODER;
27702   static constexpr auto THREAD_BROWSER_WATCHDOG = ChromeThreadDescriptor_ThreadType_THREAD_BROWSER_WATCHDOG;
27703   static constexpr auto THREAD_WEBRTC_NETWORK = ChromeThreadDescriptor_ThreadType_THREAD_WEBRTC_NETWORK;
27704   static constexpr auto THREAD_WINDOW_OWNER = ChromeThreadDescriptor_ThreadType_THREAD_WINDOW_OWNER;
27705   static constexpr auto THREAD_WEBRTC_SIGNALING = ChromeThreadDescriptor_ThreadType_THREAD_WEBRTC_SIGNALING;
27706   static constexpr auto THREAD_WEBRTC_WORKER = ChromeThreadDescriptor_ThreadType_THREAD_WEBRTC_WORKER;
27707   static constexpr auto THREAD_PPAPI_MAIN = ChromeThreadDescriptor_ThreadType_THREAD_PPAPI_MAIN;
27708   static constexpr auto THREAD_GPU_WATCHDOG = ChromeThreadDescriptor_ThreadType_THREAD_GPU_WATCHDOG;
27709   static constexpr auto THREAD_SWAPPER = ChromeThreadDescriptor_ThreadType_THREAD_SWAPPER;
27710   static constexpr auto THREAD_GAMEPAD_POLLING = ChromeThreadDescriptor_ThreadType_THREAD_GAMEPAD_POLLING;
27711   static constexpr auto THREAD_WEBCRYPTO = ChromeThreadDescriptor_ThreadType_THREAD_WEBCRYPTO;
27712   static constexpr auto THREAD_DATABASE = ChromeThreadDescriptor_ThreadType_THREAD_DATABASE;
27713   static constexpr auto THREAD_PROXYRESOLVER = ChromeThreadDescriptor_ThreadType_THREAD_PROXYRESOLVER;
27714   static constexpr auto THREAD_DEVTOOLSADB = ChromeThreadDescriptor_ThreadType_THREAD_DEVTOOLSADB;
27715   static constexpr auto THREAD_NETWORKCONFIGWATCHER = ChromeThreadDescriptor_ThreadType_THREAD_NETWORKCONFIGWATCHER;
27716   static constexpr auto THREAD_WASAPI_RENDER = ChromeThreadDescriptor_ThreadType_THREAD_WASAPI_RENDER;
27717   static constexpr auto THREAD_MEMORY_INFRA = ChromeThreadDescriptor_ThreadType_THREAD_MEMORY_INFRA;
27718   static constexpr auto THREAD_SAMPLING_PROFILER = ChromeThreadDescriptor_ThreadType_THREAD_SAMPLING_PROFILER;
27719   static constexpr auto ThreadType_MIN = ChromeThreadDescriptor_ThreadType_THREAD_UNSPECIFIED;
27720   static constexpr auto ThreadType_MAX = ChromeThreadDescriptor_ThreadType_THREAD_SAMPLING_PROFILER;
27721   enum FieldNumbers {
27722     kThreadTypeFieldNumber = 1,
27723     kLegacySortIndexFieldNumber = 2,
27724   };
27725 
27726   ChromeThreadDescriptor();
27727   ~ChromeThreadDescriptor() override;
27728   ChromeThreadDescriptor(ChromeThreadDescriptor&&) noexcept;
27729   ChromeThreadDescriptor& operator=(ChromeThreadDescriptor&&);
27730   ChromeThreadDescriptor(const ChromeThreadDescriptor&);
27731   ChromeThreadDescriptor& operator=(const ChromeThreadDescriptor&);
27732   bool operator==(const ChromeThreadDescriptor&) const;
operator !=(const ChromeThreadDescriptor & other) const27733   bool operator!=(const ChromeThreadDescriptor& other) const { return !(*this == other); }
27734 
27735   bool ParseFromArray(const void*, size_t) override;
27736   std::string SerializeAsString() const override;
27737   std::vector<uint8_t> SerializeAsArray() const override;
27738   void Serialize(::protozero::Message*) const;
27739 
has_thread_type() const27740   bool has_thread_type() const { return _has_field_[1]; }
thread_type() const27741   ChromeThreadDescriptor_ThreadType thread_type() const { return thread_type_; }
set_thread_type(ChromeThreadDescriptor_ThreadType value)27742   void set_thread_type(ChromeThreadDescriptor_ThreadType value) { thread_type_ = value; _has_field_.set(1); }
27743 
has_legacy_sort_index() const27744   bool has_legacy_sort_index() const { return _has_field_[2]; }
legacy_sort_index() const27745   int32_t legacy_sort_index() const { return legacy_sort_index_; }
set_legacy_sort_index(int32_t value)27746   void set_legacy_sort_index(int32_t value) { legacy_sort_index_ = value; _has_field_.set(2); }
27747 
27748  private:
27749   ChromeThreadDescriptor_ThreadType thread_type_{};
27750   int32_t legacy_sort_index_{};
27751 
27752   // Allows to preserve unknown protobuf fields for compatibility
27753   // with future versions of .proto files.
27754   std::string unknown_fields_;
27755 
27756   std::bitset<3> _has_field_{};
27757 };
27758 
27759 }  // namespace perfetto
27760 }  // namespace protos
27761 }  // namespace gen
27762 
27763 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_THREAD_DESCRIPTOR_PROTO_CPP_H_
27764 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
27765 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
27766 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
27767 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
27768 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
27769 #if defined(__GNUC__) || defined(__clang__)
27770 #pragma GCC diagnostic push
27771 #pragma GCC diagnostic ignored "-Wfloat-equal"
27772 #endif
27773 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_thread_descriptor.gen.h"
27774 
27775 namespace perfetto {
27776 namespace protos {
27777 namespace gen {
27778 
27779 ChromeThreadDescriptor::ChromeThreadDescriptor() = default;
27780 ChromeThreadDescriptor::~ChromeThreadDescriptor() = default;
27781 ChromeThreadDescriptor::ChromeThreadDescriptor(const ChromeThreadDescriptor&) = default;
27782 ChromeThreadDescriptor& ChromeThreadDescriptor::operator=(const ChromeThreadDescriptor&) = default;
27783 ChromeThreadDescriptor::ChromeThreadDescriptor(ChromeThreadDescriptor&&) noexcept = default;
27784 ChromeThreadDescriptor& ChromeThreadDescriptor::operator=(ChromeThreadDescriptor&&) = default;
27785 
operator ==(const ChromeThreadDescriptor & other) const27786 bool ChromeThreadDescriptor::operator==(const ChromeThreadDescriptor& other) const {
27787   return unknown_fields_ == other.unknown_fields_
27788    && thread_type_ == other.thread_type_
27789    && legacy_sort_index_ == other.legacy_sort_index_;
27790 }
27791 
ParseFromArray(const void * raw,size_t size)27792 bool ChromeThreadDescriptor::ParseFromArray(const void* raw, size_t size) {
27793   unknown_fields_.clear();
27794   bool packed_error = false;
27795 
27796   ::protozero::ProtoDecoder dec(raw, size);
27797   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
27798     if (field.id() < _has_field_.size()) {
27799       _has_field_.set(field.id());
27800     }
27801     switch (field.id()) {
27802       case 1 /* thread_type */:
27803         field.get(&thread_type_);
27804         break;
27805       case 2 /* legacy_sort_index */:
27806         field.get(&legacy_sort_index_);
27807         break;
27808       default:
27809         field.SerializeAndAppendTo(&unknown_fields_);
27810         break;
27811     }
27812   }
27813   return !packed_error && !dec.bytes_left();
27814 }
27815 
SerializeAsString() const27816 std::string ChromeThreadDescriptor::SerializeAsString() const {
27817   ::protozero::HeapBuffered<::protozero::Message> msg;
27818   Serialize(msg.get());
27819   return msg.SerializeAsString();
27820 }
27821 
SerializeAsArray() const27822 std::vector<uint8_t> ChromeThreadDescriptor::SerializeAsArray() const {
27823   ::protozero::HeapBuffered<::protozero::Message> msg;
27824   Serialize(msg.get());
27825   return msg.SerializeAsArray();
27826 }
27827 
Serialize(::protozero::Message * msg) const27828 void ChromeThreadDescriptor::Serialize(::protozero::Message* msg) const {
27829   // Field 1: thread_type
27830   if (_has_field_[1]) {
27831     msg->AppendVarInt(1, thread_type_);
27832   }
27833 
27834   // Field 2: legacy_sort_index
27835   if (_has_field_[2]) {
27836     msg->AppendVarInt(2, legacy_sort_index_);
27837   }
27838 
27839   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
27840 }
27841 
27842 }  // namespace perfetto
27843 }  // namespace protos
27844 }  // namespace gen
27845 #if defined(__GNUC__) || defined(__clang__)
27846 #pragma GCC diagnostic pop
27847 #endif
27848 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_user_event.gen.cc
27849 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_user_event.gen.h
27850 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
27851 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_USER_EVENT_PROTO_CPP_H_
27852 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_USER_EVENT_PROTO_CPP_H_
27853 
27854 #include <stdint.h>
27855 #include <bitset>
27856 #include <vector>
27857 #include <string>
27858 #include <type_traits>
27859 
27860 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
27861 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
27862 // gen_amalgamated expanded: #include "perfetto/base/export.h"
27863 
27864 namespace perfetto {
27865 namespace protos {
27866 namespace gen {
27867 class ChromeUserEvent;
27868 }  // namespace perfetto
27869 }  // namespace protos
27870 }  // namespace gen
27871 
27872 namespace protozero {
27873 class Message;
27874 }  // namespace protozero
27875 
27876 namespace perfetto {
27877 namespace protos {
27878 namespace gen {
27879 
27880 class PERFETTO_EXPORT ChromeUserEvent : public ::protozero::CppMessageObj {
27881  public:
27882   enum FieldNumbers {
27883     kActionFieldNumber = 1,
27884     kActionHashFieldNumber = 2,
27885   };
27886 
27887   ChromeUserEvent();
27888   ~ChromeUserEvent() override;
27889   ChromeUserEvent(ChromeUserEvent&&) noexcept;
27890   ChromeUserEvent& operator=(ChromeUserEvent&&);
27891   ChromeUserEvent(const ChromeUserEvent&);
27892   ChromeUserEvent& operator=(const ChromeUserEvent&);
27893   bool operator==(const ChromeUserEvent&) const;
operator !=(const ChromeUserEvent & other) const27894   bool operator!=(const ChromeUserEvent& other) const { return !(*this == other); }
27895 
27896   bool ParseFromArray(const void*, size_t) override;
27897   std::string SerializeAsString() const override;
27898   std::vector<uint8_t> SerializeAsArray() const override;
27899   void Serialize(::protozero::Message*) const;
27900 
has_action() const27901   bool has_action() const { return _has_field_[1]; }
action() const27902   const std::string& action() const { return action_; }
set_action(const std::string & value)27903   void set_action(const std::string& value) { action_ = value; _has_field_.set(1); }
27904 
has_action_hash() const27905   bool has_action_hash() const { return _has_field_[2]; }
action_hash() const27906   uint64_t action_hash() const { return action_hash_; }
set_action_hash(uint64_t value)27907   void set_action_hash(uint64_t value) { action_hash_ = value; _has_field_.set(2); }
27908 
27909  private:
27910   std::string action_{};
27911   uint64_t action_hash_{};
27912 
27913   // Allows to preserve unknown protobuf fields for compatibility
27914   // with future versions of .proto files.
27915   std::string unknown_fields_;
27916 
27917   std::bitset<3> _has_field_{};
27918 };
27919 
27920 }  // namespace perfetto
27921 }  // namespace protos
27922 }  // namespace gen
27923 
27924 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_USER_EVENT_PROTO_CPP_H_
27925 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
27926 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
27927 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
27928 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
27929 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
27930 #if defined(__GNUC__) || defined(__clang__)
27931 #pragma GCC diagnostic push
27932 #pragma GCC diagnostic ignored "-Wfloat-equal"
27933 #endif
27934 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_user_event.gen.h"
27935 
27936 namespace perfetto {
27937 namespace protos {
27938 namespace gen {
27939 
27940 ChromeUserEvent::ChromeUserEvent() = default;
27941 ChromeUserEvent::~ChromeUserEvent() = default;
27942 ChromeUserEvent::ChromeUserEvent(const ChromeUserEvent&) = default;
27943 ChromeUserEvent& ChromeUserEvent::operator=(const ChromeUserEvent&) = default;
27944 ChromeUserEvent::ChromeUserEvent(ChromeUserEvent&&) noexcept = default;
27945 ChromeUserEvent& ChromeUserEvent::operator=(ChromeUserEvent&&) = default;
27946 
operator ==(const ChromeUserEvent & other) const27947 bool ChromeUserEvent::operator==(const ChromeUserEvent& other) const {
27948   return unknown_fields_ == other.unknown_fields_
27949    && action_ == other.action_
27950    && action_hash_ == other.action_hash_;
27951 }
27952 
ParseFromArray(const void * raw,size_t size)27953 bool ChromeUserEvent::ParseFromArray(const void* raw, size_t size) {
27954   unknown_fields_.clear();
27955   bool packed_error = false;
27956 
27957   ::protozero::ProtoDecoder dec(raw, size);
27958   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
27959     if (field.id() < _has_field_.size()) {
27960       _has_field_.set(field.id());
27961     }
27962     switch (field.id()) {
27963       case 1 /* action */:
27964         field.get(&action_);
27965         break;
27966       case 2 /* action_hash */:
27967         field.get(&action_hash_);
27968         break;
27969       default:
27970         field.SerializeAndAppendTo(&unknown_fields_);
27971         break;
27972     }
27973   }
27974   return !packed_error && !dec.bytes_left();
27975 }
27976 
SerializeAsString() const27977 std::string ChromeUserEvent::SerializeAsString() const {
27978   ::protozero::HeapBuffered<::protozero::Message> msg;
27979   Serialize(msg.get());
27980   return msg.SerializeAsString();
27981 }
27982 
SerializeAsArray() const27983 std::vector<uint8_t> ChromeUserEvent::SerializeAsArray() const {
27984   ::protozero::HeapBuffered<::protozero::Message> msg;
27985   Serialize(msg.get());
27986   return msg.SerializeAsArray();
27987 }
27988 
Serialize(::protozero::Message * msg) const27989 void ChromeUserEvent::Serialize(::protozero::Message* msg) const {
27990   // Field 1: action
27991   if (_has_field_[1]) {
27992     msg->AppendString(1, action_);
27993   }
27994 
27995   // Field 2: action_hash
27996   if (_has_field_[2]) {
27997     msg->AppendVarInt(2, action_hash_);
27998   }
27999 
28000   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
28001 }
28002 
28003 }  // namespace perfetto
28004 }  // namespace protos
28005 }  // namespace gen
28006 #if defined(__GNUC__) || defined(__clang__)
28007 #pragma GCC diagnostic pop
28008 #endif
28009 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_window_handle_event_info.gen.cc
28010 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_window_handle_event_info.gen.h
28011 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
28012 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_WINDOW_HANDLE_EVENT_INFO_PROTO_CPP_H_
28013 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_WINDOW_HANDLE_EVENT_INFO_PROTO_CPP_H_
28014 
28015 #include <stdint.h>
28016 #include <bitset>
28017 #include <vector>
28018 #include <string>
28019 #include <type_traits>
28020 
28021 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
28022 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
28023 // gen_amalgamated expanded: #include "perfetto/base/export.h"
28024 
28025 namespace perfetto {
28026 namespace protos {
28027 namespace gen {
28028 class ChromeWindowHandleEventInfo;
28029 }  // namespace perfetto
28030 }  // namespace protos
28031 }  // namespace gen
28032 
28033 namespace protozero {
28034 class Message;
28035 }  // namespace protozero
28036 
28037 namespace perfetto {
28038 namespace protos {
28039 namespace gen {
28040 
28041 class PERFETTO_EXPORT ChromeWindowHandleEventInfo : public ::protozero::CppMessageObj {
28042  public:
28043   enum FieldNumbers {
28044     kDpiFieldNumber = 1,
28045     kMessageIdFieldNumber = 2,
28046     kHwndPtrFieldNumber = 3,
28047   };
28048 
28049   ChromeWindowHandleEventInfo();
28050   ~ChromeWindowHandleEventInfo() override;
28051   ChromeWindowHandleEventInfo(ChromeWindowHandleEventInfo&&) noexcept;
28052   ChromeWindowHandleEventInfo& operator=(ChromeWindowHandleEventInfo&&);
28053   ChromeWindowHandleEventInfo(const ChromeWindowHandleEventInfo&);
28054   ChromeWindowHandleEventInfo& operator=(const ChromeWindowHandleEventInfo&);
28055   bool operator==(const ChromeWindowHandleEventInfo&) const;
operator !=(const ChromeWindowHandleEventInfo & other) const28056   bool operator!=(const ChromeWindowHandleEventInfo& other) const { return !(*this == other); }
28057 
28058   bool ParseFromArray(const void*, size_t) override;
28059   std::string SerializeAsString() const override;
28060   std::vector<uint8_t> SerializeAsArray() const override;
28061   void Serialize(::protozero::Message*) const;
28062 
has_dpi() const28063   bool has_dpi() const { return _has_field_[1]; }
dpi() const28064   uint32_t dpi() const { return dpi_; }
set_dpi(uint32_t value)28065   void set_dpi(uint32_t value) { dpi_ = value; _has_field_.set(1); }
28066 
has_message_id() const28067   bool has_message_id() const { return _has_field_[2]; }
message_id() const28068   uint32_t message_id() const { return message_id_; }
set_message_id(uint32_t value)28069   void set_message_id(uint32_t value) { message_id_ = value; _has_field_.set(2); }
28070 
has_hwnd_ptr() const28071   bool has_hwnd_ptr() const { return _has_field_[3]; }
hwnd_ptr() const28072   uint64_t hwnd_ptr() const { return hwnd_ptr_; }
set_hwnd_ptr(uint64_t value)28073   void set_hwnd_ptr(uint64_t value) { hwnd_ptr_ = value; _has_field_.set(3); }
28074 
28075  private:
28076   uint32_t dpi_{};
28077   uint32_t message_id_{};
28078   uint64_t hwnd_ptr_{};
28079 
28080   // Allows to preserve unknown protobuf fields for compatibility
28081   // with future versions of .proto files.
28082   std::string unknown_fields_;
28083 
28084   std::bitset<4> _has_field_{};
28085 };
28086 
28087 }  // namespace perfetto
28088 }  // namespace protos
28089 }  // namespace gen
28090 
28091 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_WINDOW_HANDLE_EVENT_INFO_PROTO_CPP_H_
28092 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
28093 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
28094 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
28095 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
28096 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
28097 #if defined(__GNUC__) || defined(__clang__)
28098 #pragma GCC diagnostic push
28099 #pragma GCC diagnostic ignored "-Wfloat-equal"
28100 #endif
28101 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_window_handle_event_info.gen.h"
28102 
28103 namespace perfetto {
28104 namespace protos {
28105 namespace gen {
28106 
28107 ChromeWindowHandleEventInfo::ChromeWindowHandleEventInfo() = default;
28108 ChromeWindowHandleEventInfo::~ChromeWindowHandleEventInfo() = default;
28109 ChromeWindowHandleEventInfo::ChromeWindowHandleEventInfo(const ChromeWindowHandleEventInfo&) = default;
28110 ChromeWindowHandleEventInfo& ChromeWindowHandleEventInfo::operator=(const ChromeWindowHandleEventInfo&) = default;
28111 ChromeWindowHandleEventInfo::ChromeWindowHandleEventInfo(ChromeWindowHandleEventInfo&&) noexcept = default;
28112 ChromeWindowHandleEventInfo& ChromeWindowHandleEventInfo::operator=(ChromeWindowHandleEventInfo&&) = default;
28113 
operator ==(const ChromeWindowHandleEventInfo & other) const28114 bool ChromeWindowHandleEventInfo::operator==(const ChromeWindowHandleEventInfo& other) const {
28115   return unknown_fields_ == other.unknown_fields_
28116    && dpi_ == other.dpi_
28117    && message_id_ == other.message_id_
28118    && hwnd_ptr_ == other.hwnd_ptr_;
28119 }
28120 
ParseFromArray(const void * raw,size_t size)28121 bool ChromeWindowHandleEventInfo::ParseFromArray(const void* raw, size_t size) {
28122   unknown_fields_.clear();
28123   bool packed_error = false;
28124 
28125   ::protozero::ProtoDecoder dec(raw, size);
28126   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
28127     if (field.id() < _has_field_.size()) {
28128       _has_field_.set(field.id());
28129     }
28130     switch (field.id()) {
28131       case 1 /* dpi */:
28132         field.get(&dpi_);
28133         break;
28134       case 2 /* message_id */:
28135         field.get(&message_id_);
28136         break;
28137       case 3 /* hwnd_ptr */:
28138         field.get(&hwnd_ptr_);
28139         break;
28140       default:
28141         field.SerializeAndAppendTo(&unknown_fields_);
28142         break;
28143     }
28144   }
28145   return !packed_error && !dec.bytes_left();
28146 }
28147 
SerializeAsString() const28148 std::string ChromeWindowHandleEventInfo::SerializeAsString() const {
28149   ::protozero::HeapBuffered<::protozero::Message> msg;
28150   Serialize(msg.get());
28151   return msg.SerializeAsString();
28152 }
28153 
SerializeAsArray() const28154 std::vector<uint8_t> ChromeWindowHandleEventInfo::SerializeAsArray() const {
28155   ::protozero::HeapBuffered<::protozero::Message> msg;
28156   Serialize(msg.get());
28157   return msg.SerializeAsArray();
28158 }
28159 
Serialize(::protozero::Message * msg) const28160 void ChromeWindowHandleEventInfo::Serialize(::protozero::Message* msg) const {
28161   // Field 1: dpi
28162   if (_has_field_[1]) {
28163     msg->AppendVarInt(1, dpi_);
28164   }
28165 
28166   // Field 2: message_id
28167   if (_has_field_[2]) {
28168     msg->AppendVarInt(2, message_id_);
28169   }
28170 
28171   // Field 3: hwnd_ptr
28172   if (_has_field_[3]) {
28173     msg->AppendFixed(3, hwnd_ptr_);
28174   }
28175 
28176   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
28177 }
28178 
28179 }  // namespace perfetto
28180 }  // namespace protos
28181 }  // namespace gen
28182 #if defined(__GNUC__) || defined(__clang__)
28183 #pragma GCC diagnostic pop
28184 #endif
28185 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/counter_descriptor.gen.cc
28186 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/counter_descriptor.gen.h
28187 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
28188 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_COUNTER_DESCRIPTOR_PROTO_CPP_H_
28189 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_COUNTER_DESCRIPTOR_PROTO_CPP_H_
28190 
28191 #include <stdint.h>
28192 #include <bitset>
28193 #include <vector>
28194 #include <string>
28195 #include <type_traits>
28196 
28197 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
28198 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
28199 // gen_amalgamated expanded: #include "perfetto/base/export.h"
28200 
28201 namespace perfetto {
28202 namespace protos {
28203 namespace gen {
28204 class CounterDescriptor;
28205 enum CounterDescriptor_BuiltinCounterType : int;
28206 enum CounterDescriptor_Unit : int;
28207 }  // namespace perfetto
28208 }  // namespace protos
28209 }  // namespace gen
28210 
28211 namespace protozero {
28212 class Message;
28213 }  // namespace protozero
28214 
28215 namespace perfetto {
28216 namespace protos {
28217 namespace gen {
28218 enum CounterDescriptor_BuiltinCounterType : int {
28219   CounterDescriptor_BuiltinCounterType_COUNTER_UNSPECIFIED = 0,
28220   CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_TIME_NS = 1,
28221   CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_INSTRUCTION_COUNT = 2,
28222 };
28223 enum CounterDescriptor_Unit : int {
28224   CounterDescriptor_Unit_UNIT_UNSPECIFIED = 0,
28225   CounterDescriptor_Unit_UNIT_TIME_NS = 1,
28226   CounterDescriptor_Unit_UNIT_COUNT = 2,
28227   CounterDescriptor_Unit_UNIT_SIZE_BYTES = 3,
28228 };
28229 
28230 class PERFETTO_EXPORT CounterDescriptor : public ::protozero::CppMessageObj {
28231  public:
28232   using BuiltinCounterType = CounterDescriptor_BuiltinCounterType;
28233   static constexpr auto COUNTER_UNSPECIFIED = CounterDescriptor_BuiltinCounterType_COUNTER_UNSPECIFIED;
28234   static constexpr auto COUNTER_THREAD_TIME_NS = CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_TIME_NS;
28235   static constexpr auto COUNTER_THREAD_INSTRUCTION_COUNT = CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_INSTRUCTION_COUNT;
28236   static constexpr auto BuiltinCounterType_MIN = CounterDescriptor_BuiltinCounterType_COUNTER_UNSPECIFIED;
28237   static constexpr auto BuiltinCounterType_MAX = CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_INSTRUCTION_COUNT;
28238   using Unit = CounterDescriptor_Unit;
28239   static constexpr auto UNIT_UNSPECIFIED = CounterDescriptor_Unit_UNIT_UNSPECIFIED;
28240   static constexpr auto UNIT_TIME_NS = CounterDescriptor_Unit_UNIT_TIME_NS;
28241   static constexpr auto UNIT_COUNT = CounterDescriptor_Unit_UNIT_COUNT;
28242   static constexpr auto UNIT_SIZE_BYTES = CounterDescriptor_Unit_UNIT_SIZE_BYTES;
28243   static constexpr auto Unit_MIN = CounterDescriptor_Unit_UNIT_UNSPECIFIED;
28244   static constexpr auto Unit_MAX = CounterDescriptor_Unit_UNIT_SIZE_BYTES;
28245   enum FieldNumbers {
28246     kTypeFieldNumber = 1,
28247     kCategoriesFieldNumber = 2,
28248     kUnitFieldNumber = 3,
28249     kUnitNameFieldNumber = 6,
28250     kUnitMultiplierFieldNumber = 4,
28251     kIsIncrementalFieldNumber = 5,
28252   };
28253 
28254   CounterDescriptor();
28255   ~CounterDescriptor() override;
28256   CounterDescriptor(CounterDescriptor&&) noexcept;
28257   CounterDescriptor& operator=(CounterDescriptor&&);
28258   CounterDescriptor(const CounterDescriptor&);
28259   CounterDescriptor& operator=(const CounterDescriptor&);
28260   bool operator==(const CounterDescriptor&) const;
operator !=(const CounterDescriptor & other) const28261   bool operator!=(const CounterDescriptor& other) const { return !(*this == other); }
28262 
28263   bool ParseFromArray(const void*, size_t) override;
28264   std::string SerializeAsString() const override;
28265   std::vector<uint8_t> SerializeAsArray() const override;
28266   void Serialize(::protozero::Message*) const;
28267 
has_type() const28268   bool has_type() const { return _has_field_[1]; }
type() const28269   CounterDescriptor_BuiltinCounterType type() const { return type_; }
set_type(CounterDescriptor_BuiltinCounterType value)28270   void set_type(CounterDescriptor_BuiltinCounterType value) { type_ = value; _has_field_.set(1); }
28271 
categories() const28272   const std::vector<std::string>& categories() const { return categories_; }
mutable_categories()28273   std::vector<std::string>* mutable_categories() { return &categories_; }
categories_size() const28274   int categories_size() const { return static_cast<int>(categories_.size()); }
clear_categories()28275   void clear_categories() { categories_.clear(); }
add_categories(std::string value)28276   void add_categories(std::string value) { categories_.emplace_back(value); }
add_categories()28277   std::string* add_categories() { categories_.emplace_back(); return &categories_.back(); }
28278 
has_unit() const28279   bool has_unit() const { return _has_field_[3]; }
unit() const28280   CounterDescriptor_Unit unit() const { return unit_; }
set_unit(CounterDescriptor_Unit value)28281   void set_unit(CounterDescriptor_Unit value) { unit_ = value; _has_field_.set(3); }
28282 
has_unit_name() const28283   bool has_unit_name() const { return _has_field_[6]; }
unit_name() const28284   const std::string& unit_name() const { return unit_name_; }
set_unit_name(const std::string & value)28285   void set_unit_name(const std::string& value) { unit_name_ = value; _has_field_.set(6); }
28286 
has_unit_multiplier() const28287   bool has_unit_multiplier() const { return _has_field_[4]; }
unit_multiplier() const28288   int64_t unit_multiplier() const { return unit_multiplier_; }
set_unit_multiplier(int64_t value)28289   void set_unit_multiplier(int64_t value) { unit_multiplier_ = value; _has_field_.set(4); }
28290 
has_is_incremental() const28291   bool has_is_incremental() const { return _has_field_[5]; }
is_incremental() const28292   bool is_incremental() const { return is_incremental_; }
set_is_incremental(bool value)28293   void set_is_incremental(bool value) { is_incremental_ = value; _has_field_.set(5); }
28294 
28295  private:
28296   CounterDescriptor_BuiltinCounterType type_{};
28297   std::vector<std::string> categories_;
28298   CounterDescriptor_Unit unit_{};
28299   std::string unit_name_{};
28300   int64_t unit_multiplier_{};
28301   bool is_incremental_{};
28302 
28303   // Allows to preserve unknown protobuf fields for compatibility
28304   // with future versions of .proto files.
28305   std::string unknown_fields_;
28306 
28307   std::bitset<7> _has_field_{};
28308 };
28309 
28310 }  // namespace perfetto
28311 }  // namespace protos
28312 }  // namespace gen
28313 
28314 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_COUNTER_DESCRIPTOR_PROTO_CPP_H_
28315 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
28316 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
28317 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
28318 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
28319 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
28320 #if defined(__GNUC__) || defined(__clang__)
28321 #pragma GCC diagnostic push
28322 #pragma GCC diagnostic ignored "-Wfloat-equal"
28323 #endif
28324 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/counter_descriptor.gen.h"
28325 
28326 namespace perfetto {
28327 namespace protos {
28328 namespace gen {
28329 
28330 CounterDescriptor::CounterDescriptor() = default;
28331 CounterDescriptor::~CounterDescriptor() = default;
28332 CounterDescriptor::CounterDescriptor(const CounterDescriptor&) = default;
28333 CounterDescriptor& CounterDescriptor::operator=(const CounterDescriptor&) = default;
28334 CounterDescriptor::CounterDescriptor(CounterDescriptor&&) noexcept = default;
28335 CounterDescriptor& CounterDescriptor::operator=(CounterDescriptor&&) = default;
28336 
operator ==(const CounterDescriptor & other) const28337 bool CounterDescriptor::operator==(const CounterDescriptor& other) const {
28338   return unknown_fields_ == other.unknown_fields_
28339    && type_ == other.type_
28340    && categories_ == other.categories_
28341    && unit_ == other.unit_
28342    && unit_name_ == other.unit_name_
28343    && unit_multiplier_ == other.unit_multiplier_
28344    && is_incremental_ == other.is_incremental_;
28345 }
28346 
ParseFromArray(const void * raw,size_t size)28347 bool CounterDescriptor::ParseFromArray(const void* raw, size_t size) {
28348   categories_.clear();
28349   unknown_fields_.clear();
28350   bool packed_error = false;
28351 
28352   ::protozero::ProtoDecoder dec(raw, size);
28353   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
28354     if (field.id() < _has_field_.size()) {
28355       _has_field_.set(field.id());
28356     }
28357     switch (field.id()) {
28358       case 1 /* type */:
28359         field.get(&type_);
28360         break;
28361       case 2 /* categories */:
28362         categories_.emplace_back();
28363         field.get(&categories_.back());
28364         break;
28365       case 3 /* unit */:
28366         field.get(&unit_);
28367         break;
28368       case 6 /* unit_name */:
28369         field.get(&unit_name_);
28370         break;
28371       case 4 /* unit_multiplier */:
28372         field.get(&unit_multiplier_);
28373         break;
28374       case 5 /* is_incremental */:
28375         field.get(&is_incremental_);
28376         break;
28377       default:
28378         field.SerializeAndAppendTo(&unknown_fields_);
28379         break;
28380     }
28381   }
28382   return !packed_error && !dec.bytes_left();
28383 }
28384 
SerializeAsString() const28385 std::string CounterDescriptor::SerializeAsString() const {
28386   ::protozero::HeapBuffered<::protozero::Message> msg;
28387   Serialize(msg.get());
28388   return msg.SerializeAsString();
28389 }
28390 
SerializeAsArray() const28391 std::vector<uint8_t> CounterDescriptor::SerializeAsArray() const {
28392   ::protozero::HeapBuffered<::protozero::Message> msg;
28393   Serialize(msg.get());
28394   return msg.SerializeAsArray();
28395 }
28396 
Serialize(::protozero::Message * msg) const28397 void CounterDescriptor::Serialize(::protozero::Message* msg) const {
28398   // Field 1: type
28399   if (_has_field_[1]) {
28400     msg->AppendVarInt(1, type_);
28401   }
28402 
28403   // Field 2: categories
28404   for (auto& it : categories_) {
28405     msg->AppendString(2, it);
28406   }
28407 
28408   // Field 3: unit
28409   if (_has_field_[3]) {
28410     msg->AppendVarInt(3, unit_);
28411   }
28412 
28413   // Field 6: unit_name
28414   if (_has_field_[6]) {
28415     msg->AppendString(6, unit_name_);
28416   }
28417 
28418   // Field 4: unit_multiplier
28419   if (_has_field_[4]) {
28420     msg->AppendVarInt(4, unit_multiplier_);
28421   }
28422 
28423   // Field 5: is_incremental
28424   if (_has_field_[5]) {
28425     msg->AppendTinyVarInt(5, is_incremental_);
28426   }
28427 
28428   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
28429 }
28430 
28431 }  // namespace perfetto
28432 }  // namespace protos
28433 }  // namespace gen
28434 #if defined(__GNUC__) || defined(__clang__)
28435 #pragma GCC diagnostic pop
28436 #endif
28437 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/debug_annotation.gen.cc
28438 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/debug_annotation.gen.h
28439 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
28440 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_DEBUG_ANNOTATION_PROTO_CPP_H_
28441 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_DEBUG_ANNOTATION_PROTO_CPP_H_
28442 
28443 #include <stdint.h>
28444 #include <bitset>
28445 #include <vector>
28446 #include <string>
28447 #include <type_traits>
28448 
28449 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
28450 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
28451 // gen_amalgamated expanded: #include "perfetto/base/export.h"
28452 
28453 namespace perfetto {
28454 namespace protos {
28455 namespace gen {
28456 class DebugAnnotationName;
28457 class DebugAnnotation;
28458 class DebugAnnotation_NestedValue;
28459 enum DebugAnnotation_NestedValue_NestedType : int;
28460 }  // namespace perfetto
28461 }  // namespace protos
28462 }  // namespace gen
28463 
28464 namespace protozero {
28465 class Message;
28466 }  // namespace protozero
28467 
28468 namespace perfetto {
28469 namespace protos {
28470 namespace gen {
28471 enum DebugAnnotation_NestedValue_NestedType : int {
28472   DebugAnnotation_NestedValue_NestedType_UNSPECIFIED = 0,
28473   DebugAnnotation_NestedValue_NestedType_DICT = 1,
28474   DebugAnnotation_NestedValue_NestedType_ARRAY = 2,
28475 };
28476 
28477 class PERFETTO_EXPORT DebugAnnotationName : public ::protozero::CppMessageObj {
28478  public:
28479   enum FieldNumbers {
28480     kIidFieldNumber = 1,
28481     kNameFieldNumber = 2,
28482   };
28483 
28484   DebugAnnotationName();
28485   ~DebugAnnotationName() override;
28486   DebugAnnotationName(DebugAnnotationName&&) noexcept;
28487   DebugAnnotationName& operator=(DebugAnnotationName&&);
28488   DebugAnnotationName(const DebugAnnotationName&);
28489   DebugAnnotationName& operator=(const DebugAnnotationName&);
28490   bool operator==(const DebugAnnotationName&) const;
operator !=(const DebugAnnotationName & other) const28491   bool operator!=(const DebugAnnotationName& other) const { return !(*this == other); }
28492 
28493   bool ParseFromArray(const void*, size_t) override;
28494   std::string SerializeAsString() const override;
28495   std::vector<uint8_t> SerializeAsArray() const override;
28496   void Serialize(::protozero::Message*) const;
28497 
has_iid() const28498   bool has_iid() const { return _has_field_[1]; }
iid() const28499   uint64_t iid() const { return iid_; }
set_iid(uint64_t value)28500   void set_iid(uint64_t value) { iid_ = value; _has_field_.set(1); }
28501 
has_name() const28502   bool has_name() const { return _has_field_[2]; }
name() const28503   const std::string& name() const { return name_; }
set_name(const std::string & value)28504   void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
28505 
28506  private:
28507   uint64_t iid_{};
28508   std::string name_{};
28509 
28510   // Allows to preserve unknown protobuf fields for compatibility
28511   // with future versions of .proto files.
28512   std::string unknown_fields_;
28513 
28514   std::bitset<3> _has_field_{};
28515 };
28516 
28517 
28518 class PERFETTO_EXPORT DebugAnnotation : public ::protozero::CppMessageObj {
28519  public:
28520   using NestedValue = DebugAnnotation_NestedValue;
28521   enum FieldNumbers {
28522     kNameIidFieldNumber = 1,
28523     kNameFieldNumber = 10,
28524     kBoolValueFieldNumber = 2,
28525     kUintValueFieldNumber = 3,
28526     kIntValueFieldNumber = 4,
28527     kDoubleValueFieldNumber = 5,
28528     kStringValueFieldNumber = 6,
28529     kPointerValueFieldNumber = 7,
28530     kNestedValueFieldNumber = 8,
28531     kLegacyJsonValueFieldNumber = 9,
28532     kDictEntriesFieldNumber = 11,
28533     kArrayValuesFieldNumber = 12,
28534   };
28535 
28536   DebugAnnotation();
28537   ~DebugAnnotation() override;
28538   DebugAnnotation(DebugAnnotation&&) noexcept;
28539   DebugAnnotation& operator=(DebugAnnotation&&);
28540   DebugAnnotation(const DebugAnnotation&);
28541   DebugAnnotation& operator=(const DebugAnnotation&);
28542   bool operator==(const DebugAnnotation&) const;
operator !=(const DebugAnnotation & other) const28543   bool operator!=(const DebugAnnotation& other) const { return !(*this == other); }
28544 
28545   bool ParseFromArray(const void*, size_t) override;
28546   std::string SerializeAsString() const override;
28547   std::vector<uint8_t> SerializeAsArray() const override;
28548   void Serialize(::protozero::Message*) const;
28549 
has_name_iid() const28550   bool has_name_iid() const { return _has_field_[1]; }
name_iid() const28551   uint64_t name_iid() const { return name_iid_; }
set_name_iid(uint64_t value)28552   void set_name_iid(uint64_t value) { name_iid_ = value; _has_field_.set(1); }
28553 
has_name() const28554   bool has_name() const { return _has_field_[10]; }
name() const28555   const std::string& name() const { return name_; }
set_name(const std::string & value)28556   void set_name(const std::string& value) { name_ = value; _has_field_.set(10); }
28557 
has_bool_value() const28558   bool has_bool_value() const { return _has_field_[2]; }
bool_value() const28559   bool bool_value() const { return bool_value_; }
set_bool_value(bool value)28560   void set_bool_value(bool value) { bool_value_ = value; _has_field_.set(2); }
28561 
has_uint_value() const28562   bool has_uint_value() const { return _has_field_[3]; }
uint_value() const28563   uint64_t uint_value() const { return uint_value_; }
set_uint_value(uint64_t value)28564   void set_uint_value(uint64_t value) { uint_value_ = value; _has_field_.set(3); }
28565 
has_int_value() const28566   bool has_int_value() const { return _has_field_[4]; }
int_value() const28567   int64_t int_value() const { return int_value_; }
set_int_value(int64_t value)28568   void set_int_value(int64_t value) { int_value_ = value; _has_field_.set(4); }
28569 
has_double_value() const28570   bool has_double_value() const { return _has_field_[5]; }
double_value() const28571   double double_value() const { return double_value_; }
set_double_value(double value)28572   void set_double_value(double value) { double_value_ = value; _has_field_.set(5); }
28573 
has_string_value() const28574   bool has_string_value() const { return _has_field_[6]; }
string_value() const28575   const std::string& string_value() const { return string_value_; }
set_string_value(const std::string & value)28576   void set_string_value(const std::string& value) { string_value_ = value; _has_field_.set(6); }
28577 
has_pointer_value() const28578   bool has_pointer_value() const { return _has_field_[7]; }
pointer_value() const28579   uint64_t pointer_value() const { return pointer_value_; }
set_pointer_value(uint64_t value)28580   void set_pointer_value(uint64_t value) { pointer_value_ = value; _has_field_.set(7); }
28581 
has_nested_value() const28582   bool has_nested_value() const { return _has_field_[8]; }
nested_value() const28583   const DebugAnnotation_NestedValue& nested_value() const { return *nested_value_; }
mutable_nested_value()28584   DebugAnnotation_NestedValue* mutable_nested_value() { _has_field_.set(8); return nested_value_.get(); }
28585 
has_legacy_json_value() const28586   bool has_legacy_json_value() const { return _has_field_[9]; }
legacy_json_value() const28587   const std::string& legacy_json_value() const { return legacy_json_value_; }
set_legacy_json_value(const std::string & value)28588   void set_legacy_json_value(const std::string& value) { legacy_json_value_ = value; _has_field_.set(9); }
28589 
dict_entries() const28590   const std::vector<DebugAnnotation>& dict_entries() const { return dict_entries_; }
mutable_dict_entries()28591   std::vector<DebugAnnotation>* mutable_dict_entries() { return &dict_entries_; }
28592   int dict_entries_size() const;
28593   void clear_dict_entries();
28594   DebugAnnotation* add_dict_entries();
28595 
array_values() const28596   const std::vector<DebugAnnotation>& array_values() const { return array_values_; }
mutable_array_values()28597   std::vector<DebugAnnotation>* mutable_array_values() { return &array_values_; }
28598   int array_values_size() const;
28599   void clear_array_values();
28600   DebugAnnotation* add_array_values();
28601 
28602  private:
28603   uint64_t name_iid_{};
28604   std::string name_{};
28605   bool bool_value_{};
28606   uint64_t uint_value_{};
28607   int64_t int_value_{};
28608   double double_value_{};
28609   std::string string_value_{};
28610   uint64_t pointer_value_{};
28611   ::protozero::CopyablePtr<DebugAnnotation_NestedValue> nested_value_;
28612   std::string legacy_json_value_{};
28613   std::vector<DebugAnnotation> dict_entries_;
28614   std::vector<DebugAnnotation> array_values_;
28615 
28616   // Allows to preserve unknown protobuf fields for compatibility
28617   // with future versions of .proto files.
28618   std::string unknown_fields_;
28619 
28620   std::bitset<13> _has_field_{};
28621 };
28622 
28623 
28624 class PERFETTO_EXPORT DebugAnnotation_NestedValue : public ::protozero::CppMessageObj {
28625  public:
28626   using NestedType = DebugAnnotation_NestedValue_NestedType;
28627   static constexpr auto UNSPECIFIED = DebugAnnotation_NestedValue_NestedType_UNSPECIFIED;
28628   static constexpr auto DICT = DebugAnnotation_NestedValue_NestedType_DICT;
28629   static constexpr auto ARRAY = DebugAnnotation_NestedValue_NestedType_ARRAY;
28630   static constexpr auto NestedType_MIN = DebugAnnotation_NestedValue_NestedType_UNSPECIFIED;
28631   static constexpr auto NestedType_MAX = DebugAnnotation_NestedValue_NestedType_ARRAY;
28632   enum FieldNumbers {
28633     kNestedTypeFieldNumber = 1,
28634     kDictKeysFieldNumber = 2,
28635     kDictValuesFieldNumber = 3,
28636     kArrayValuesFieldNumber = 4,
28637     kIntValueFieldNumber = 5,
28638     kDoubleValueFieldNumber = 6,
28639     kBoolValueFieldNumber = 7,
28640     kStringValueFieldNumber = 8,
28641   };
28642 
28643   DebugAnnotation_NestedValue();
28644   ~DebugAnnotation_NestedValue() override;
28645   DebugAnnotation_NestedValue(DebugAnnotation_NestedValue&&) noexcept;
28646   DebugAnnotation_NestedValue& operator=(DebugAnnotation_NestedValue&&);
28647   DebugAnnotation_NestedValue(const DebugAnnotation_NestedValue&);
28648   DebugAnnotation_NestedValue& operator=(const DebugAnnotation_NestedValue&);
28649   bool operator==(const DebugAnnotation_NestedValue&) const;
operator !=(const DebugAnnotation_NestedValue & other) const28650   bool operator!=(const DebugAnnotation_NestedValue& other) const { return !(*this == other); }
28651 
28652   bool ParseFromArray(const void*, size_t) override;
28653   std::string SerializeAsString() const override;
28654   std::vector<uint8_t> SerializeAsArray() const override;
28655   void Serialize(::protozero::Message*) const;
28656 
has_nested_type() const28657   bool has_nested_type() const { return _has_field_[1]; }
nested_type() const28658   DebugAnnotation_NestedValue_NestedType nested_type() const { return nested_type_; }
set_nested_type(DebugAnnotation_NestedValue_NestedType value)28659   void set_nested_type(DebugAnnotation_NestedValue_NestedType value) { nested_type_ = value; _has_field_.set(1); }
28660 
dict_keys() const28661   const std::vector<std::string>& dict_keys() const { return dict_keys_; }
mutable_dict_keys()28662   std::vector<std::string>* mutable_dict_keys() { return &dict_keys_; }
dict_keys_size() const28663   int dict_keys_size() const { return static_cast<int>(dict_keys_.size()); }
clear_dict_keys()28664   void clear_dict_keys() { dict_keys_.clear(); }
add_dict_keys(std::string value)28665   void add_dict_keys(std::string value) { dict_keys_.emplace_back(value); }
add_dict_keys()28666   std::string* add_dict_keys() { dict_keys_.emplace_back(); return &dict_keys_.back(); }
28667 
dict_values() const28668   const std::vector<DebugAnnotation_NestedValue>& dict_values() const { return dict_values_; }
mutable_dict_values()28669   std::vector<DebugAnnotation_NestedValue>* mutable_dict_values() { return &dict_values_; }
28670   int dict_values_size() const;
28671   void clear_dict_values();
28672   DebugAnnotation_NestedValue* add_dict_values();
28673 
array_values() const28674   const std::vector<DebugAnnotation_NestedValue>& array_values() const { return array_values_; }
mutable_array_values()28675   std::vector<DebugAnnotation_NestedValue>* mutable_array_values() { return &array_values_; }
28676   int array_values_size() const;
28677   void clear_array_values();
28678   DebugAnnotation_NestedValue* add_array_values();
28679 
has_int_value() const28680   bool has_int_value() const { return _has_field_[5]; }
int_value() const28681   int64_t int_value() const { return int_value_; }
set_int_value(int64_t value)28682   void set_int_value(int64_t value) { int_value_ = value; _has_field_.set(5); }
28683 
has_double_value() const28684   bool has_double_value() const { return _has_field_[6]; }
double_value() const28685   double double_value() const { return double_value_; }
set_double_value(double value)28686   void set_double_value(double value) { double_value_ = value; _has_field_.set(6); }
28687 
has_bool_value() const28688   bool has_bool_value() const { return _has_field_[7]; }
bool_value() const28689   bool bool_value() const { return bool_value_; }
set_bool_value(bool value)28690   void set_bool_value(bool value) { bool_value_ = value; _has_field_.set(7); }
28691 
has_string_value() const28692   bool has_string_value() const { return _has_field_[8]; }
string_value() const28693   const std::string& string_value() const { return string_value_; }
set_string_value(const std::string & value)28694   void set_string_value(const std::string& value) { string_value_ = value; _has_field_.set(8); }
28695 
28696  private:
28697   DebugAnnotation_NestedValue_NestedType nested_type_{};
28698   std::vector<std::string> dict_keys_;
28699   std::vector<DebugAnnotation_NestedValue> dict_values_;
28700   std::vector<DebugAnnotation_NestedValue> array_values_;
28701   int64_t int_value_{};
28702   double double_value_{};
28703   bool bool_value_{};
28704   std::string string_value_{};
28705 
28706   // Allows to preserve unknown protobuf fields for compatibility
28707   // with future versions of .proto files.
28708   std::string unknown_fields_;
28709 
28710   std::bitset<9> _has_field_{};
28711 };
28712 
28713 }  // namespace perfetto
28714 }  // namespace protos
28715 }  // namespace gen
28716 
28717 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_DEBUG_ANNOTATION_PROTO_CPP_H_
28718 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
28719 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
28720 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
28721 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
28722 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
28723 #if defined(__GNUC__) || defined(__clang__)
28724 #pragma GCC diagnostic push
28725 #pragma GCC diagnostic ignored "-Wfloat-equal"
28726 #endif
28727 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.gen.h"
28728 
28729 namespace perfetto {
28730 namespace protos {
28731 namespace gen {
28732 
28733 DebugAnnotationName::DebugAnnotationName() = default;
28734 DebugAnnotationName::~DebugAnnotationName() = default;
28735 DebugAnnotationName::DebugAnnotationName(const DebugAnnotationName&) = default;
28736 DebugAnnotationName& DebugAnnotationName::operator=(const DebugAnnotationName&) = default;
28737 DebugAnnotationName::DebugAnnotationName(DebugAnnotationName&&) noexcept = default;
28738 DebugAnnotationName& DebugAnnotationName::operator=(DebugAnnotationName&&) = default;
28739 
operator ==(const DebugAnnotationName & other) const28740 bool DebugAnnotationName::operator==(const DebugAnnotationName& other) const {
28741   return unknown_fields_ == other.unknown_fields_
28742    && iid_ == other.iid_
28743    && name_ == other.name_;
28744 }
28745 
ParseFromArray(const void * raw,size_t size)28746 bool DebugAnnotationName::ParseFromArray(const void* raw, size_t size) {
28747   unknown_fields_.clear();
28748   bool packed_error = false;
28749 
28750   ::protozero::ProtoDecoder dec(raw, size);
28751   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
28752     if (field.id() < _has_field_.size()) {
28753       _has_field_.set(field.id());
28754     }
28755     switch (field.id()) {
28756       case 1 /* iid */:
28757         field.get(&iid_);
28758         break;
28759       case 2 /* name */:
28760         field.get(&name_);
28761         break;
28762       default:
28763         field.SerializeAndAppendTo(&unknown_fields_);
28764         break;
28765     }
28766   }
28767   return !packed_error && !dec.bytes_left();
28768 }
28769 
SerializeAsString() const28770 std::string DebugAnnotationName::SerializeAsString() const {
28771   ::protozero::HeapBuffered<::protozero::Message> msg;
28772   Serialize(msg.get());
28773   return msg.SerializeAsString();
28774 }
28775 
SerializeAsArray() const28776 std::vector<uint8_t> DebugAnnotationName::SerializeAsArray() const {
28777   ::protozero::HeapBuffered<::protozero::Message> msg;
28778   Serialize(msg.get());
28779   return msg.SerializeAsArray();
28780 }
28781 
Serialize(::protozero::Message * msg) const28782 void DebugAnnotationName::Serialize(::protozero::Message* msg) const {
28783   // Field 1: iid
28784   if (_has_field_[1]) {
28785     msg->AppendVarInt(1, iid_);
28786   }
28787 
28788   // Field 2: name
28789   if (_has_field_[2]) {
28790     msg->AppendString(2, name_);
28791   }
28792 
28793   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
28794 }
28795 
28796 
28797 DebugAnnotation::DebugAnnotation() = default;
28798 DebugAnnotation::~DebugAnnotation() = default;
28799 DebugAnnotation::DebugAnnotation(const DebugAnnotation&) = default;
28800 DebugAnnotation& DebugAnnotation::operator=(const DebugAnnotation&) = default;
28801 DebugAnnotation::DebugAnnotation(DebugAnnotation&&) noexcept = default;
28802 DebugAnnotation& DebugAnnotation::operator=(DebugAnnotation&&) = default;
28803 
operator ==(const DebugAnnotation & other) const28804 bool DebugAnnotation::operator==(const DebugAnnotation& other) const {
28805   return unknown_fields_ == other.unknown_fields_
28806    && name_iid_ == other.name_iid_
28807    && name_ == other.name_
28808    && bool_value_ == other.bool_value_
28809    && uint_value_ == other.uint_value_
28810    && int_value_ == other.int_value_
28811    && double_value_ == other.double_value_
28812    && string_value_ == other.string_value_
28813    && pointer_value_ == other.pointer_value_
28814    && nested_value_ == other.nested_value_
28815    && legacy_json_value_ == other.legacy_json_value_
28816    && dict_entries_ == other.dict_entries_
28817    && array_values_ == other.array_values_;
28818 }
28819 
dict_entries_size() const28820 int DebugAnnotation::dict_entries_size() const { return static_cast<int>(dict_entries_.size()); }
clear_dict_entries()28821 void DebugAnnotation::clear_dict_entries() { dict_entries_.clear(); }
add_dict_entries()28822 DebugAnnotation* DebugAnnotation::add_dict_entries() { dict_entries_.emplace_back(); return &dict_entries_.back(); }
array_values_size() const28823 int DebugAnnotation::array_values_size() const { return static_cast<int>(array_values_.size()); }
clear_array_values()28824 void DebugAnnotation::clear_array_values() { array_values_.clear(); }
add_array_values()28825 DebugAnnotation* DebugAnnotation::add_array_values() { array_values_.emplace_back(); return &array_values_.back(); }
ParseFromArray(const void * raw,size_t size)28826 bool DebugAnnotation::ParseFromArray(const void* raw, size_t size) {
28827   dict_entries_.clear();
28828   array_values_.clear();
28829   unknown_fields_.clear();
28830   bool packed_error = false;
28831 
28832   ::protozero::ProtoDecoder dec(raw, size);
28833   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
28834     if (field.id() < _has_field_.size()) {
28835       _has_field_.set(field.id());
28836     }
28837     switch (field.id()) {
28838       case 1 /* name_iid */:
28839         field.get(&name_iid_);
28840         break;
28841       case 10 /* name */:
28842         field.get(&name_);
28843         break;
28844       case 2 /* bool_value */:
28845         field.get(&bool_value_);
28846         break;
28847       case 3 /* uint_value */:
28848         field.get(&uint_value_);
28849         break;
28850       case 4 /* int_value */:
28851         field.get(&int_value_);
28852         break;
28853       case 5 /* double_value */:
28854         field.get(&double_value_);
28855         break;
28856       case 6 /* string_value */:
28857         field.get(&string_value_);
28858         break;
28859       case 7 /* pointer_value */:
28860         field.get(&pointer_value_);
28861         break;
28862       case 8 /* nested_value */:
28863         (*nested_value_).ParseFromArray(field.data(), field.size());
28864         break;
28865       case 9 /* legacy_json_value */:
28866         field.get(&legacy_json_value_);
28867         break;
28868       case 11 /* dict_entries */:
28869         dict_entries_.emplace_back();
28870         dict_entries_.back().ParseFromArray(field.data(), field.size());
28871         break;
28872       case 12 /* array_values */:
28873         array_values_.emplace_back();
28874         array_values_.back().ParseFromArray(field.data(), field.size());
28875         break;
28876       default:
28877         field.SerializeAndAppendTo(&unknown_fields_);
28878         break;
28879     }
28880   }
28881   return !packed_error && !dec.bytes_left();
28882 }
28883 
SerializeAsString() const28884 std::string DebugAnnotation::SerializeAsString() const {
28885   ::protozero::HeapBuffered<::protozero::Message> msg;
28886   Serialize(msg.get());
28887   return msg.SerializeAsString();
28888 }
28889 
SerializeAsArray() const28890 std::vector<uint8_t> DebugAnnotation::SerializeAsArray() const {
28891   ::protozero::HeapBuffered<::protozero::Message> msg;
28892   Serialize(msg.get());
28893   return msg.SerializeAsArray();
28894 }
28895 
Serialize(::protozero::Message * msg) const28896 void DebugAnnotation::Serialize(::protozero::Message* msg) const {
28897   // Field 1: name_iid
28898   if (_has_field_[1]) {
28899     msg->AppendVarInt(1, name_iid_);
28900   }
28901 
28902   // Field 10: name
28903   if (_has_field_[10]) {
28904     msg->AppendString(10, name_);
28905   }
28906 
28907   // Field 2: bool_value
28908   if (_has_field_[2]) {
28909     msg->AppendTinyVarInt(2, bool_value_);
28910   }
28911 
28912   // Field 3: uint_value
28913   if (_has_field_[3]) {
28914     msg->AppendVarInt(3, uint_value_);
28915   }
28916 
28917   // Field 4: int_value
28918   if (_has_field_[4]) {
28919     msg->AppendVarInt(4, int_value_);
28920   }
28921 
28922   // Field 5: double_value
28923   if (_has_field_[5]) {
28924     msg->AppendFixed(5, double_value_);
28925   }
28926 
28927   // Field 6: string_value
28928   if (_has_field_[6]) {
28929     msg->AppendString(6, string_value_);
28930   }
28931 
28932   // Field 7: pointer_value
28933   if (_has_field_[7]) {
28934     msg->AppendVarInt(7, pointer_value_);
28935   }
28936 
28937   // Field 8: nested_value
28938   if (_has_field_[8]) {
28939     (*nested_value_).Serialize(msg->BeginNestedMessage<::protozero::Message>(8));
28940   }
28941 
28942   // Field 9: legacy_json_value
28943   if (_has_field_[9]) {
28944     msg->AppendString(9, legacy_json_value_);
28945   }
28946 
28947   // Field 11: dict_entries
28948   for (auto& it : dict_entries_) {
28949     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(11));
28950   }
28951 
28952   // Field 12: array_values
28953   for (auto& it : array_values_) {
28954     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(12));
28955   }
28956 
28957   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
28958 }
28959 
28960 
28961 DebugAnnotation_NestedValue::DebugAnnotation_NestedValue() = default;
28962 DebugAnnotation_NestedValue::~DebugAnnotation_NestedValue() = default;
28963 DebugAnnotation_NestedValue::DebugAnnotation_NestedValue(const DebugAnnotation_NestedValue&) = default;
28964 DebugAnnotation_NestedValue& DebugAnnotation_NestedValue::operator=(const DebugAnnotation_NestedValue&) = default;
28965 DebugAnnotation_NestedValue::DebugAnnotation_NestedValue(DebugAnnotation_NestedValue&&) noexcept = default;
28966 DebugAnnotation_NestedValue& DebugAnnotation_NestedValue::operator=(DebugAnnotation_NestedValue&&) = default;
28967 
operator ==(const DebugAnnotation_NestedValue & other) const28968 bool DebugAnnotation_NestedValue::operator==(const DebugAnnotation_NestedValue& other) const {
28969   return unknown_fields_ == other.unknown_fields_
28970    && nested_type_ == other.nested_type_
28971    && dict_keys_ == other.dict_keys_
28972    && dict_values_ == other.dict_values_
28973    && array_values_ == other.array_values_
28974    && int_value_ == other.int_value_
28975    && double_value_ == other.double_value_
28976    && bool_value_ == other.bool_value_
28977    && string_value_ == other.string_value_;
28978 }
28979 
dict_values_size() const28980 int DebugAnnotation_NestedValue::dict_values_size() const { return static_cast<int>(dict_values_.size()); }
clear_dict_values()28981 void DebugAnnotation_NestedValue::clear_dict_values() { dict_values_.clear(); }
add_dict_values()28982 DebugAnnotation_NestedValue* DebugAnnotation_NestedValue::add_dict_values() { dict_values_.emplace_back(); return &dict_values_.back(); }
array_values_size() const28983 int DebugAnnotation_NestedValue::array_values_size() const { return static_cast<int>(array_values_.size()); }
clear_array_values()28984 void DebugAnnotation_NestedValue::clear_array_values() { array_values_.clear(); }
add_array_values()28985 DebugAnnotation_NestedValue* DebugAnnotation_NestedValue::add_array_values() { array_values_.emplace_back(); return &array_values_.back(); }
ParseFromArray(const void * raw,size_t size)28986 bool DebugAnnotation_NestedValue::ParseFromArray(const void* raw, size_t size) {
28987   dict_keys_.clear();
28988   dict_values_.clear();
28989   array_values_.clear();
28990   unknown_fields_.clear();
28991   bool packed_error = false;
28992 
28993   ::protozero::ProtoDecoder dec(raw, size);
28994   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
28995     if (field.id() < _has_field_.size()) {
28996       _has_field_.set(field.id());
28997     }
28998     switch (field.id()) {
28999       case 1 /* nested_type */:
29000         field.get(&nested_type_);
29001         break;
29002       case 2 /* dict_keys */:
29003         dict_keys_.emplace_back();
29004         field.get(&dict_keys_.back());
29005         break;
29006       case 3 /* dict_values */:
29007         dict_values_.emplace_back();
29008         dict_values_.back().ParseFromArray(field.data(), field.size());
29009         break;
29010       case 4 /* array_values */:
29011         array_values_.emplace_back();
29012         array_values_.back().ParseFromArray(field.data(), field.size());
29013         break;
29014       case 5 /* int_value */:
29015         field.get(&int_value_);
29016         break;
29017       case 6 /* double_value */:
29018         field.get(&double_value_);
29019         break;
29020       case 7 /* bool_value */:
29021         field.get(&bool_value_);
29022         break;
29023       case 8 /* string_value */:
29024         field.get(&string_value_);
29025         break;
29026       default:
29027         field.SerializeAndAppendTo(&unknown_fields_);
29028         break;
29029     }
29030   }
29031   return !packed_error && !dec.bytes_left();
29032 }
29033 
SerializeAsString() const29034 std::string DebugAnnotation_NestedValue::SerializeAsString() const {
29035   ::protozero::HeapBuffered<::protozero::Message> msg;
29036   Serialize(msg.get());
29037   return msg.SerializeAsString();
29038 }
29039 
SerializeAsArray() const29040 std::vector<uint8_t> DebugAnnotation_NestedValue::SerializeAsArray() const {
29041   ::protozero::HeapBuffered<::protozero::Message> msg;
29042   Serialize(msg.get());
29043   return msg.SerializeAsArray();
29044 }
29045 
Serialize(::protozero::Message * msg) const29046 void DebugAnnotation_NestedValue::Serialize(::protozero::Message* msg) const {
29047   // Field 1: nested_type
29048   if (_has_field_[1]) {
29049     msg->AppendVarInt(1, nested_type_);
29050   }
29051 
29052   // Field 2: dict_keys
29053   for (auto& it : dict_keys_) {
29054     msg->AppendString(2, it);
29055   }
29056 
29057   // Field 3: dict_values
29058   for (auto& it : dict_values_) {
29059     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
29060   }
29061 
29062   // Field 4: array_values
29063   for (auto& it : array_values_) {
29064     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
29065   }
29066 
29067   // Field 5: int_value
29068   if (_has_field_[5]) {
29069     msg->AppendVarInt(5, int_value_);
29070   }
29071 
29072   // Field 6: double_value
29073   if (_has_field_[6]) {
29074     msg->AppendFixed(6, double_value_);
29075   }
29076 
29077   // Field 7: bool_value
29078   if (_has_field_[7]) {
29079     msg->AppendTinyVarInt(7, bool_value_);
29080   }
29081 
29082   // Field 8: string_value
29083   if (_has_field_[8]) {
29084     msg->AppendString(8, string_value_);
29085   }
29086 
29087   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
29088 }
29089 
29090 }  // namespace perfetto
29091 }  // namespace protos
29092 }  // namespace gen
29093 #if defined(__GNUC__) || defined(__clang__)
29094 #pragma GCC diagnostic pop
29095 #endif
29096 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/log_message.gen.cc
29097 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/log_message.gen.h
29098 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
29099 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_LOG_MESSAGE_PROTO_CPP_H_
29100 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_LOG_MESSAGE_PROTO_CPP_H_
29101 
29102 #include <stdint.h>
29103 #include <bitset>
29104 #include <vector>
29105 #include <string>
29106 #include <type_traits>
29107 
29108 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
29109 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
29110 // gen_amalgamated expanded: #include "perfetto/base/export.h"
29111 
29112 namespace perfetto {
29113 namespace protos {
29114 namespace gen {
29115 class LogMessageBody;
29116 class LogMessage;
29117 }  // namespace perfetto
29118 }  // namespace protos
29119 }  // namespace gen
29120 
29121 namespace protozero {
29122 class Message;
29123 }  // namespace protozero
29124 
29125 namespace perfetto {
29126 namespace protos {
29127 namespace gen {
29128 
29129 class PERFETTO_EXPORT LogMessageBody : public ::protozero::CppMessageObj {
29130  public:
29131   enum FieldNumbers {
29132     kIidFieldNumber = 1,
29133     kBodyFieldNumber = 2,
29134   };
29135 
29136   LogMessageBody();
29137   ~LogMessageBody() override;
29138   LogMessageBody(LogMessageBody&&) noexcept;
29139   LogMessageBody& operator=(LogMessageBody&&);
29140   LogMessageBody(const LogMessageBody&);
29141   LogMessageBody& operator=(const LogMessageBody&);
29142   bool operator==(const LogMessageBody&) const;
operator !=(const LogMessageBody & other) const29143   bool operator!=(const LogMessageBody& other) const { return !(*this == other); }
29144 
29145   bool ParseFromArray(const void*, size_t) override;
29146   std::string SerializeAsString() const override;
29147   std::vector<uint8_t> SerializeAsArray() const override;
29148   void Serialize(::protozero::Message*) const;
29149 
has_iid() const29150   bool has_iid() const { return _has_field_[1]; }
iid() const29151   uint64_t iid() const { return iid_; }
set_iid(uint64_t value)29152   void set_iid(uint64_t value) { iid_ = value; _has_field_.set(1); }
29153 
has_body() const29154   bool has_body() const { return _has_field_[2]; }
body() const29155   const std::string& body() const { return body_; }
set_body(const std::string & value)29156   void set_body(const std::string& value) { body_ = value; _has_field_.set(2); }
29157 
29158  private:
29159   uint64_t iid_{};
29160   std::string body_{};
29161 
29162   // Allows to preserve unknown protobuf fields for compatibility
29163   // with future versions of .proto files.
29164   std::string unknown_fields_;
29165 
29166   std::bitset<3> _has_field_{};
29167 };
29168 
29169 
29170 class PERFETTO_EXPORT LogMessage : public ::protozero::CppMessageObj {
29171  public:
29172   enum FieldNumbers {
29173     kSourceLocationIidFieldNumber = 1,
29174     kBodyIidFieldNumber = 2,
29175   };
29176 
29177   LogMessage();
29178   ~LogMessage() override;
29179   LogMessage(LogMessage&&) noexcept;
29180   LogMessage& operator=(LogMessage&&);
29181   LogMessage(const LogMessage&);
29182   LogMessage& operator=(const LogMessage&);
29183   bool operator==(const LogMessage&) const;
operator !=(const LogMessage & other) const29184   bool operator!=(const LogMessage& other) const { return !(*this == other); }
29185 
29186   bool ParseFromArray(const void*, size_t) override;
29187   std::string SerializeAsString() const override;
29188   std::vector<uint8_t> SerializeAsArray() const override;
29189   void Serialize(::protozero::Message*) const;
29190 
has_source_location_iid() const29191   bool has_source_location_iid() const { return _has_field_[1]; }
source_location_iid() const29192   uint64_t source_location_iid() const { return source_location_iid_; }
set_source_location_iid(uint64_t value)29193   void set_source_location_iid(uint64_t value) { source_location_iid_ = value; _has_field_.set(1); }
29194 
has_body_iid() const29195   bool has_body_iid() const { return _has_field_[2]; }
body_iid() const29196   uint64_t body_iid() const { return body_iid_; }
set_body_iid(uint64_t value)29197   void set_body_iid(uint64_t value) { body_iid_ = value; _has_field_.set(2); }
29198 
29199  private:
29200   uint64_t source_location_iid_{};
29201   uint64_t body_iid_{};
29202 
29203   // Allows to preserve unknown protobuf fields for compatibility
29204   // with future versions of .proto files.
29205   std::string unknown_fields_;
29206 
29207   std::bitset<3> _has_field_{};
29208 };
29209 
29210 }  // namespace perfetto
29211 }  // namespace protos
29212 }  // namespace gen
29213 
29214 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_LOG_MESSAGE_PROTO_CPP_H_
29215 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
29216 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
29217 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
29218 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
29219 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
29220 #if defined(__GNUC__) || defined(__clang__)
29221 #pragma GCC diagnostic push
29222 #pragma GCC diagnostic ignored "-Wfloat-equal"
29223 #endif
29224 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/log_message.gen.h"
29225 
29226 namespace perfetto {
29227 namespace protos {
29228 namespace gen {
29229 
29230 LogMessageBody::LogMessageBody() = default;
29231 LogMessageBody::~LogMessageBody() = default;
29232 LogMessageBody::LogMessageBody(const LogMessageBody&) = default;
29233 LogMessageBody& LogMessageBody::operator=(const LogMessageBody&) = default;
29234 LogMessageBody::LogMessageBody(LogMessageBody&&) noexcept = default;
29235 LogMessageBody& LogMessageBody::operator=(LogMessageBody&&) = default;
29236 
operator ==(const LogMessageBody & other) const29237 bool LogMessageBody::operator==(const LogMessageBody& other) const {
29238   return unknown_fields_ == other.unknown_fields_
29239    && iid_ == other.iid_
29240    && body_ == other.body_;
29241 }
29242 
ParseFromArray(const void * raw,size_t size)29243 bool LogMessageBody::ParseFromArray(const void* raw, size_t size) {
29244   unknown_fields_.clear();
29245   bool packed_error = false;
29246 
29247   ::protozero::ProtoDecoder dec(raw, size);
29248   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
29249     if (field.id() < _has_field_.size()) {
29250       _has_field_.set(field.id());
29251     }
29252     switch (field.id()) {
29253       case 1 /* iid */:
29254         field.get(&iid_);
29255         break;
29256       case 2 /* body */:
29257         field.get(&body_);
29258         break;
29259       default:
29260         field.SerializeAndAppendTo(&unknown_fields_);
29261         break;
29262     }
29263   }
29264   return !packed_error && !dec.bytes_left();
29265 }
29266 
SerializeAsString() const29267 std::string LogMessageBody::SerializeAsString() const {
29268   ::protozero::HeapBuffered<::protozero::Message> msg;
29269   Serialize(msg.get());
29270   return msg.SerializeAsString();
29271 }
29272 
SerializeAsArray() const29273 std::vector<uint8_t> LogMessageBody::SerializeAsArray() const {
29274   ::protozero::HeapBuffered<::protozero::Message> msg;
29275   Serialize(msg.get());
29276   return msg.SerializeAsArray();
29277 }
29278 
Serialize(::protozero::Message * msg) const29279 void LogMessageBody::Serialize(::protozero::Message* msg) const {
29280   // Field 1: iid
29281   if (_has_field_[1]) {
29282     msg->AppendVarInt(1, iid_);
29283   }
29284 
29285   // Field 2: body
29286   if (_has_field_[2]) {
29287     msg->AppendString(2, body_);
29288   }
29289 
29290   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
29291 }
29292 
29293 
29294 LogMessage::LogMessage() = default;
29295 LogMessage::~LogMessage() = default;
29296 LogMessage::LogMessage(const LogMessage&) = default;
29297 LogMessage& LogMessage::operator=(const LogMessage&) = default;
29298 LogMessage::LogMessage(LogMessage&&) noexcept = default;
29299 LogMessage& LogMessage::operator=(LogMessage&&) = default;
29300 
operator ==(const LogMessage & other) const29301 bool LogMessage::operator==(const LogMessage& other) const {
29302   return unknown_fields_ == other.unknown_fields_
29303    && source_location_iid_ == other.source_location_iid_
29304    && body_iid_ == other.body_iid_;
29305 }
29306 
ParseFromArray(const void * raw,size_t size)29307 bool LogMessage::ParseFromArray(const void* raw, size_t size) {
29308   unknown_fields_.clear();
29309   bool packed_error = false;
29310 
29311   ::protozero::ProtoDecoder dec(raw, size);
29312   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
29313     if (field.id() < _has_field_.size()) {
29314       _has_field_.set(field.id());
29315     }
29316     switch (field.id()) {
29317       case 1 /* source_location_iid */:
29318         field.get(&source_location_iid_);
29319         break;
29320       case 2 /* body_iid */:
29321         field.get(&body_iid_);
29322         break;
29323       default:
29324         field.SerializeAndAppendTo(&unknown_fields_);
29325         break;
29326     }
29327   }
29328   return !packed_error && !dec.bytes_left();
29329 }
29330 
SerializeAsString() const29331 std::string LogMessage::SerializeAsString() const {
29332   ::protozero::HeapBuffered<::protozero::Message> msg;
29333   Serialize(msg.get());
29334   return msg.SerializeAsString();
29335 }
29336 
SerializeAsArray() const29337 std::vector<uint8_t> LogMessage::SerializeAsArray() const {
29338   ::protozero::HeapBuffered<::protozero::Message> msg;
29339   Serialize(msg.get());
29340   return msg.SerializeAsArray();
29341 }
29342 
Serialize(::protozero::Message * msg) const29343 void LogMessage::Serialize(::protozero::Message* msg) const {
29344   // Field 1: source_location_iid
29345   if (_has_field_[1]) {
29346     msg->AppendVarInt(1, source_location_iid_);
29347   }
29348 
29349   // Field 2: body_iid
29350   if (_has_field_[2]) {
29351     msg->AppendVarInt(2, body_iid_);
29352   }
29353 
29354   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
29355 }
29356 
29357 }  // namespace perfetto
29358 }  // namespace protos
29359 }  // namespace gen
29360 #if defined(__GNUC__) || defined(__clang__)
29361 #pragma GCC diagnostic pop
29362 #endif
29363 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/process_descriptor.gen.cc
29364 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/process_descriptor.gen.h
29365 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
29366 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_PROCESS_DESCRIPTOR_PROTO_CPP_H_
29367 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_PROCESS_DESCRIPTOR_PROTO_CPP_H_
29368 
29369 #include <stdint.h>
29370 #include <bitset>
29371 #include <vector>
29372 #include <string>
29373 #include <type_traits>
29374 
29375 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
29376 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
29377 // gen_amalgamated expanded: #include "perfetto/base/export.h"
29378 
29379 namespace perfetto {
29380 namespace protos {
29381 namespace gen {
29382 class ProcessDescriptor;
29383 enum ProcessDescriptor_ChromeProcessType : int;
29384 }  // namespace perfetto
29385 }  // namespace protos
29386 }  // namespace gen
29387 
29388 namespace protozero {
29389 class Message;
29390 }  // namespace protozero
29391 
29392 namespace perfetto {
29393 namespace protos {
29394 namespace gen {
29395 enum ProcessDescriptor_ChromeProcessType : int {
29396   ProcessDescriptor_ChromeProcessType_PROCESS_UNSPECIFIED = 0,
29397   ProcessDescriptor_ChromeProcessType_PROCESS_BROWSER = 1,
29398   ProcessDescriptor_ChromeProcessType_PROCESS_RENDERER = 2,
29399   ProcessDescriptor_ChromeProcessType_PROCESS_UTILITY = 3,
29400   ProcessDescriptor_ChromeProcessType_PROCESS_ZYGOTE = 4,
29401   ProcessDescriptor_ChromeProcessType_PROCESS_SANDBOX_HELPER = 5,
29402   ProcessDescriptor_ChromeProcessType_PROCESS_GPU = 6,
29403   ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_PLUGIN = 7,
29404   ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_BROKER = 8,
29405 };
29406 
29407 class PERFETTO_EXPORT ProcessDescriptor : public ::protozero::CppMessageObj {
29408  public:
29409   using ChromeProcessType = ProcessDescriptor_ChromeProcessType;
29410   static constexpr auto PROCESS_UNSPECIFIED = ProcessDescriptor_ChromeProcessType_PROCESS_UNSPECIFIED;
29411   static constexpr auto PROCESS_BROWSER = ProcessDescriptor_ChromeProcessType_PROCESS_BROWSER;
29412   static constexpr auto PROCESS_RENDERER = ProcessDescriptor_ChromeProcessType_PROCESS_RENDERER;
29413   static constexpr auto PROCESS_UTILITY = ProcessDescriptor_ChromeProcessType_PROCESS_UTILITY;
29414   static constexpr auto PROCESS_ZYGOTE = ProcessDescriptor_ChromeProcessType_PROCESS_ZYGOTE;
29415   static constexpr auto PROCESS_SANDBOX_HELPER = ProcessDescriptor_ChromeProcessType_PROCESS_SANDBOX_HELPER;
29416   static constexpr auto PROCESS_GPU = ProcessDescriptor_ChromeProcessType_PROCESS_GPU;
29417   static constexpr auto PROCESS_PPAPI_PLUGIN = ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_PLUGIN;
29418   static constexpr auto PROCESS_PPAPI_BROKER = ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_BROKER;
29419   static constexpr auto ChromeProcessType_MIN = ProcessDescriptor_ChromeProcessType_PROCESS_UNSPECIFIED;
29420   static constexpr auto ChromeProcessType_MAX = ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_BROKER;
29421   enum FieldNumbers {
29422     kPidFieldNumber = 1,
29423     kCmdlineFieldNumber = 2,
29424     kProcessNameFieldNumber = 6,
29425     kProcessPriorityFieldNumber = 5,
29426     kStartTimestampNsFieldNumber = 7,
29427     kChromeProcessTypeFieldNumber = 4,
29428     kLegacySortIndexFieldNumber = 3,
29429   };
29430 
29431   ProcessDescriptor();
29432   ~ProcessDescriptor() override;
29433   ProcessDescriptor(ProcessDescriptor&&) noexcept;
29434   ProcessDescriptor& operator=(ProcessDescriptor&&);
29435   ProcessDescriptor(const ProcessDescriptor&);
29436   ProcessDescriptor& operator=(const ProcessDescriptor&);
29437   bool operator==(const ProcessDescriptor&) const;
operator !=(const ProcessDescriptor & other) const29438   bool operator!=(const ProcessDescriptor& other) const { return !(*this == other); }
29439 
29440   bool ParseFromArray(const void*, size_t) override;
29441   std::string SerializeAsString() const override;
29442   std::vector<uint8_t> SerializeAsArray() const override;
29443   void Serialize(::protozero::Message*) const;
29444 
has_pid() const29445   bool has_pid() const { return _has_field_[1]; }
pid() const29446   int32_t pid() const { return pid_; }
set_pid(int32_t value)29447   void set_pid(int32_t value) { pid_ = value; _has_field_.set(1); }
29448 
cmdline() const29449   const std::vector<std::string>& cmdline() const { return cmdline_; }
mutable_cmdline()29450   std::vector<std::string>* mutable_cmdline() { return &cmdline_; }
cmdline_size() const29451   int cmdline_size() const { return static_cast<int>(cmdline_.size()); }
clear_cmdline()29452   void clear_cmdline() { cmdline_.clear(); }
add_cmdline(std::string value)29453   void add_cmdline(std::string value) { cmdline_.emplace_back(value); }
add_cmdline()29454   std::string* add_cmdline() { cmdline_.emplace_back(); return &cmdline_.back(); }
29455 
has_process_name() const29456   bool has_process_name() const { return _has_field_[6]; }
process_name() const29457   const std::string& process_name() const { return process_name_; }
set_process_name(const std::string & value)29458   void set_process_name(const std::string& value) { process_name_ = value; _has_field_.set(6); }
29459 
has_process_priority() const29460   bool has_process_priority() const { return _has_field_[5]; }
process_priority() const29461   int32_t process_priority() const { return process_priority_; }
set_process_priority(int32_t value)29462   void set_process_priority(int32_t value) { process_priority_ = value; _has_field_.set(5); }
29463 
has_start_timestamp_ns() const29464   bool has_start_timestamp_ns() const { return _has_field_[7]; }
start_timestamp_ns() const29465   int64_t start_timestamp_ns() const { return start_timestamp_ns_; }
set_start_timestamp_ns(int64_t value)29466   void set_start_timestamp_ns(int64_t value) { start_timestamp_ns_ = value; _has_field_.set(7); }
29467 
has_chrome_process_type() const29468   bool has_chrome_process_type() const { return _has_field_[4]; }
chrome_process_type() const29469   ProcessDescriptor_ChromeProcessType chrome_process_type() const { return chrome_process_type_; }
set_chrome_process_type(ProcessDescriptor_ChromeProcessType value)29470   void set_chrome_process_type(ProcessDescriptor_ChromeProcessType value) { chrome_process_type_ = value; _has_field_.set(4); }
29471 
has_legacy_sort_index() const29472   bool has_legacy_sort_index() const { return _has_field_[3]; }
legacy_sort_index() const29473   int32_t legacy_sort_index() const { return legacy_sort_index_; }
set_legacy_sort_index(int32_t value)29474   void set_legacy_sort_index(int32_t value) { legacy_sort_index_ = value; _has_field_.set(3); }
29475 
29476  private:
29477   int32_t pid_{};
29478   std::vector<std::string> cmdline_;
29479   std::string process_name_{};
29480   int32_t process_priority_{};
29481   int64_t start_timestamp_ns_{};
29482   ProcessDescriptor_ChromeProcessType chrome_process_type_{};
29483   int32_t legacy_sort_index_{};
29484 
29485   // Allows to preserve unknown protobuf fields for compatibility
29486   // with future versions of .proto files.
29487   std::string unknown_fields_;
29488 
29489   std::bitset<8> _has_field_{};
29490 };
29491 
29492 }  // namespace perfetto
29493 }  // namespace protos
29494 }  // namespace gen
29495 
29496 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_PROCESS_DESCRIPTOR_PROTO_CPP_H_
29497 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
29498 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
29499 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
29500 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
29501 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
29502 #if defined(__GNUC__) || defined(__clang__)
29503 #pragma GCC diagnostic push
29504 #pragma GCC diagnostic ignored "-Wfloat-equal"
29505 #endif
29506 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/process_descriptor.gen.h"
29507 
29508 namespace perfetto {
29509 namespace protos {
29510 namespace gen {
29511 
29512 ProcessDescriptor::ProcessDescriptor() = default;
29513 ProcessDescriptor::~ProcessDescriptor() = default;
29514 ProcessDescriptor::ProcessDescriptor(const ProcessDescriptor&) = default;
29515 ProcessDescriptor& ProcessDescriptor::operator=(const ProcessDescriptor&) = default;
29516 ProcessDescriptor::ProcessDescriptor(ProcessDescriptor&&) noexcept = default;
29517 ProcessDescriptor& ProcessDescriptor::operator=(ProcessDescriptor&&) = default;
29518 
operator ==(const ProcessDescriptor & other) const29519 bool ProcessDescriptor::operator==(const ProcessDescriptor& other) const {
29520   return unknown_fields_ == other.unknown_fields_
29521    && pid_ == other.pid_
29522    && cmdline_ == other.cmdline_
29523    && process_name_ == other.process_name_
29524    && process_priority_ == other.process_priority_
29525    && start_timestamp_ns_ == other.start_timestamp_ns_
29526    && chrome_process_type_ == other.chrome_process_type_
29527    && legacy_sort_index_ == other.legacy_sort_index_;
29528 }
29529 
ParseFromArray(const void * raw,size_t size)29530 bool ProcessDescriptor::ParseFromArray(const void* raw, size_t size) {
29531   cmdline_.clear();
29532   unknown_fields_.clear();
29533   bool packed_error = false;
29534 
29535   ::protozero::ProtoDecoder dec(raw, size);
29536   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
29537     if (field.id() < _has_field_.size()) {
29538       _has_field_.set(field.id());
29539     }
29540     switch (field.id()) {
29541       case 1 /* pid */:
29542         field.get(&pid_);
29543         break;
29544       case 2 /* cmdline */:
29545         cmdline_.emplace_back();
29546         field.get(&cmdline_.back());
29547         break;
29548       case 6 /* process_name */:
29549         field.get(&process_name_);
29550         break;
29551       case 5 /* process_priority */:
29552         field.get(&process_priority_);
29553         break;
29554       case 7 /* start_timestamp_ns */:
29555         field.get(&start_timestamp_ns_);
29556         break;
29557       case 4 /* chrome_process_type */:
29558         field.get(&chrome_process_type_);
29559         break;
29560       case 3 /* legacy_sort_index */:
29561         field.get(&legacy_sort_index_);
29562         break;
29563       default:
29564         field.SerializeAndAppendTo(&unknown_fields_);
29565         break;
29566     }
29567   }
29568   return !packed_error && !dec.bytes_left();
29569 }
29570 
SerializeAsString() const29571 std::string ProcessDescriptor::SerializeAsString() const {
29572   ::protozero::HeapBuffered<::protozero::Message> msg;
29573   Serialize(msg.get());
29574   return msg.SerializeAsString();
29575 }
29576 
SerializeAsArray() const29577 std::vector<uint8_t> ProcessDescriptor::SerializeAsArray() const {
29578   ::protozero::HeapBuffered<::protozero::Message> msg;
29579   Serialize(msg.get());
29580   return msg.SerializeAsArray();
29581 }
29582 
Serialize(::protozero::Message * msg) const29583 void ProcessDescriptor::Serialize(::protozero::Message* msg) const {
29584   // Field 1: pid
29585   if (_has_field_[1]) {
29586     msg->AppendVarInt(1, pid_);
29587   }
29588 
29589   // Field 2: cmdline
29590   for (auto& it : cmdline_) {
29591     msg->AppendString(2, it);
29592   }
29593 
29594   // Field 6: process_name
29595   if (_has_field_[6]) {
29596     msg->AppendString(6, process_name_);
29597   }
29598 
29599   // Field 5: process_priority
29600   if (_has_field_[5]) {
29601     msg->AppendVarInt(5, process_priority_);
29602   }
29603 
29604   // Field 7: start_timestamp_ns
29605   if (_has_field_[7]) {
29606     msg->AppendVarInt(7, start_timestamp_ns_);
29607   }
29608 
29609   // Field 4: chrome_process_type
29610   if (_has_field_[4]) {
29611     msg->AppendVarInt(4, chrome_process_type_);
29612   }
29613 
29614   // Field 3: legacy_sort_index
29615   if (_has_field_[3]) {
29616     msg->AppendVarInt(3, legacy_sort_index_);
29617   }
29618 
29619   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
29620 }
29621 
29622 }  // namespace perfetto
29623 }  // namespace protos
29624 }  // namespace gen
29625 #if defined(__GNUC__) || defined(__clang__)
29626 #pragma GCC diagnostic pop
29627 #endif
29628 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/source_location.gen.cc
29629 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
29630 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
29631 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
29632 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
29633 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
29634 #if defined(__GNUC__) || defined(__clang__)
29635 #pragma GCC diagnostic push
29636 #pragma GCC diagnostic ignored "-Wfloat-equal"
29637 #endif
29638 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/source_location.gen.h"
29639 
29640 namespace perfetto {
29641 namespace protos {
29642 namespace gen {
29643 
29644 SourceLocation::SourceLocation() = default;
29645 SourceLocation::~SourceLocation() = default;
29646 SourceLocation::SourceLocation(const SourceLocation&) = default;
29647 SourceLocation& SourceLocation::operator=(const SourceLocation&) = default;
29648 SourceLocation::SourceLocation(SourceLocation&&) noexcept = default;
29649 SourceLocation& SourceLocation::operator=(SourceLocation&&) = default;
29650 
operator ==(const SourceLocation & other) const29651 bool SourceLocation::operator==(const SourceLocation& other) const {
29652   return unknown_fields_ == other.unknown_fields_
29653    && iid_ == other.iid_
29654    && file_name_ == other.file_name_
29655    && function_name_ == other.function_name_
29656    && line_number_ == other.line_number_;
29657 }
29658 
ParseFromArray(const void * raw,size_t size)29659 bool SourceLocation::ParseFromArray(const void* raw, size_t size) {
29660   unknown_fields_.clear();
29661   bool packed_error = false;
29662 
29663   ::protozero::ProtoDecoder dec(raw, size);
29664   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
29665     if (field.id() < _has_field_.size()) {
29666       _has_field_.set(field.id());
29667     }
29668     switch (field.id()) {
29669       case 1 /* iid */:
29670         field.get(&iid_);
29671         break;
29672       case 2 /* file_name */:
29673         field.get(&file_name_);
29674         break;
29675       case 3 /* function_name */:
29676         field.get(&function_name_);
29677         break;
29678       case 4 /* line_number */:
29679         field.get(&line_number_);
29680         break;
29681       default:
29682         field.SerializeAndAppendTo(&unknown_fields_);
29683         break;
29684     }
29685   }
29686   return !packed_error && !dec.bytes_left();
29687 }
29688 
SerializeAsString() const29689 std::string SourceLocation::SerializeAsString() const {
29690   ::protozero::HeapBuffered<::protozero::Message> msg;
29691   Serialize(msg.get());
29692   return msg.SerializeAsString();
29693 }
29694 
SerializeAsArray() const29695 std::vector<uint8_t> SourceLocation::SerializeAsArray() const {
29696   ::protozero::HeapBuffered<::protozero::Message> msg;
29697   Serialize(msg.get());
29698   return msg.SerializeAsArray();
29699 }
29700 
Serialize(::protozero::Message * msg) const29701 void SourceLocation::Serialize(::protozero::Message* msg) const {
29702   // Field 1: iid
29703   if (_has_field_[1]) {
29704     msg->AppendVarInt(1, iid_);
29705   }
29706 
29707   // Field 2: file_name
29708   if (_has_field_[2]) {
29709     msg->AppendString(2, file_name_);
29710   }
29711 
29712   // Field 3: function_name
29713   if (_has_field_[3]) {
29714     msg->AppendString(3, function_name_);
29715   }
29716 
29717   // Field 4: line_number
29718   if (_has_field_[4]) {
29719     msg->AppendVarInt(4, line_number_);
29720   }
29721 
29722   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
29723 }
29724 
29725 }  // namespace perfetto
29726 }  // namespace protos
29727 }  // namespace gen
29728 #if defined(__GNUC__) || defined(__clang__)
29729 #pragma GCC diagnostic pop
29730 #endif
29731 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/task_execution.gen.cc
29732 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/task_execution.gen.h
29733 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
29734 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TASK_EXECUTION_PROTO_CPP_H_
29735 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TASK_EXECUTION_PROTO_CPP_H_
29736 
29737 #include <stdint.h>
29738 #include <bitset>
29739 #include <vector>
29740 #include <string>
29741 #include <type_traits>
29742 
29743 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
29744 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
29745 // gen_amalgamated expanded: #include "perfetto/base/export.h"
29746 
29747 namespace perfetto {
29748 namespace protos {
29749 namespace gen {
29750 class TaskExecution;
29751 }  // namespace perfetto
29752 }  // namespace protos
29753 }  // namespace gen
29754 
29755 namespace protozero {
29756 class Message;
29757 }  // namespace protozero
29758 
29759 namespace perfetto {
29760 namespace protos {
29761 namespace gen {
29762 
29763 class PERFETTO_EXPORT TaskExecution : public ::protozero::CppMessageObj {
29764  public:
29765   enum FieldNumbers {
29766     kPostedFromIidFieldNumber = 1,
29767   };
29768 
29769   TaskExecution();
29770   ~TaskExecution() override;
29771   TaskExecution(TaskExecution&&) noexcept;
29772   TaskExecution& operator=(TaskExecution&&);
29773   TaskExecution(const TaskExecution&);
29774   TaskExecution& operator=(const TaskExecution&);
29775   bool operator==(const TaskExecution&) const;
operator !=(const TaskExecution & other) const29776   bool operator!=(const TaskExecution& other) const { return !(*this == other); }
29777 
29778   bool ParseFromArray(const void*, size_t) override;
29779   std::string SerializeAsString() const override;
29780   std::vector<uint8_t> SerializeAsArray() const override;
29781   void Serialize(::protozero::Message*) const;
29782 
has_posted_from_iid() const29783   bool has_posted_from_iid() const { return _has_field_[1]; }
posted_from_iid() const29784   uint64_t posted_from_iid() const { return posted_from_iid_; }
set_posted_from_iid(uint64_t value)29785   void set_posted_from_iid(uint64_t value) { posted_from_iid_ = value; _has_field_.set(1); }
29786 
29787  private:
29788   uint64_t posted_from_iid_{};
29789 
29790   // Allows to preserve unknown protobuf fields for compatibility
29791   // with future versions of .proto files.
29792   std::string unknown_fields_;
29793 
29794   std::bitset<2> _has_field_{};
29795 };
29796 
29797 }  // namespace perfetto
29798 }  // namespace protos
29799 }  // namespace gen
29800 
29801 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TASK_EXECUTION_PROTO_CPP_H_
29802 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
29803 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
29804 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
29805 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
29806 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
29807 #if defined(__GNUC__) || defined(__clang__)
29808 #pragma GCC diagnostic push
29809 #pragma GCC diagnostic ignored "-Wfloat-equal"
29810 #endif
29811 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/task_execution.gen.h"
29812 
29813 namespace perfetto {
29814 namespace protos {
29815 namespace gen {
29816 
29817 TaskExecution::TaskExecution() = default;
29818 TaskExecution::~TaskExecution() = default;
29819 TaskExecution::TaskExecution(const TaskExecution&) = default;
29820 TaskExecution& TaskExecution::operator=(const TaskExecution&) = default;
29821 TaskExecution::TaskExecution(TaskExecution&&) noexcept = default;
29822 TaskExecution& TaskExecution::operator=(TaskExecution&&) = default;
29823 
operator ==(const TaskExecution & other) const29824 bool TaskExecution::operator==(const TaskExecution& other) const {
29825   return unknown_fields_ == other.unknown_fields_
29826    && posted_from_iid_ == other.posted_from_iid_;
29827 }
29828 
ParseFromArray(const void * raw,size_t size)29829 bool TaskExecution::ParseFromArray(const void* raw, size_t size) {
29830   unknown_fields_.clear();
29831   bool packed_error = false;
29832 
29833   ::protozero::ProtoDecoder dec(raw, size);
29834   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
29835     if (field.id() < _has_field_.size()) {
29836       _has_field_.set(field.id());
29837     }
29838     switch (field.id()) {
29839       case 1 /* posted_from_iid */:
29840         field.get(&posted_from_iid_);
29841         break;
29842       default:
29843         field.SerializeAndAppendTo(&unknown_fields_);
29844         break;
29845     }
29846   }
29847   return !packed_error && !dec.bytes_left();
29848 }
29849 
SerializeAsString() const29850 std::string TaskExecution::SerializeAsString() const {
29851   ::protozero::HeapBuffered<::protozero::Message> msg;
29852   Serialize(msg.get());
29853   return msg.SerializeAsString();
29854 }
29855 
SerializeAsArray() const29856 std::vector<uint8_t> TaskExecution::SerializeAsArray() const {
29857   ::protozero::HeapBuffered<::protozero::Message> msg;
29858   Serialize(msg.get());
29859   return msg.SerializeAsArray();
29860 }
29861 
Serialize(::protozero::Message * msg) const29862 void TaskExecution::Serialize(::protozero::Message* msg) const {
29863   // Field 1: posted_from_iid
29864   if (_has_field_[1]) {
29865     msg->AppendVarInt(1, posted_from_iid_);
29866   }
29867 
29868   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
29869 }
29870 
29871 }  // namespace perfetto
29872 }  // namespace protos
29873 }  // namespace gen
29874 #if defined(__GNUC__) || defined(__clang__)
29875 #pragma GCC diagnostic pop
29876 #endif
29877 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/thread_descriptor.gen.cc
29878 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/thread_descriptor.gen.h
29879 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
29880 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_THREAD_DESCRIPTOR_PROTO_CPP_H_
29881 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_THREAD_DESCRIPTOR_PROTO_CPP_H_
29882 
29883 #include <stdint.h>
29884 #include <bitset>
29885 #include <vector>
29886 #include <string>
29887 #include <type_traits>
29888 
29889 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
29890 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
29891 // gen_amalgamated expanded: #include "perfetto/base/export.h"
29892 
29893 namespace perfetto {
29894 namespace protos {
29895 namespace gen {
29896 class ThreadDescriptor;
29897 enum ThreadDescriptor_ChromeThreadType : int;
29898 }  // namespace perfetto
29899 }  // namespace protos
29900 }  // namespace gen
29901 
29902 namespace protozero {
29903 class Message;
29904 }  // namespace protozero
29905 
29906 namespace perfetto {
29907 namespace protos {
29908 namespace gen {
29909 enum ThreadDescriptor_ChromeThreadType : int {
29910   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_UNSPECIFIED = 0,
29911   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MAIN = 1,
29912   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_IO = 2,
29913   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_WORKER = 3,
29914   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FG_WORKER = 4,
29915   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FB_BLOCKING = 5,
29916   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_BLOCKING = 6,
29917   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_SERVICE = 7,
29918   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR = 8,
29919   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_VIZ_COMPOSITOR = 9,
29920   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR_WORKER = 10,
29921   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SERVICE_WORKER = 11,
29922   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MEMORY_INFRA = 50,
29923   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SAMPLING_PROFILER = 51,
29924 };
29925 
29926 class PERFETTO_EXPORT ThreadDescriptor : public ::protozero::CppMessageObj {
29927  public:
29928   using ChromeThreadType = ThreadDescriptor_ChromeThreadType;
29929   static constexpr auto CHROME_THREAD_UNSPECIFIED = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_UNSPECIFIED;
29930   static constexpr auto CHROME_THREAD_MAIN = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MAIN;
29931   static constexpr auto CHROME_THREAD_IO = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_IO;
29932   static constexpr auto CHROME_THREAD_POOL_BG_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_WORKER;
29933   static constexpr auto CHROME_THREAD_POOL_FG_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FG_WORKER;
29934   static constexpr auto CHROME_THREAD_POOL_FB_BLOCKING = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FB_BLOCKING;
29935   static constexpr auto CHROME_THREAD_POOL_BG_BLOCKING = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_BLOCKING;
29936   static constexpr auto CHROME_THREAD_POOL_SERVICE = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_SERVICE;
29937   static constexpr auto CHROME_THREAD_COMPOSITOR = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR;
29938   static constexpr auto CHROME_THREAD_VIZ_COMPOSITOR = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_VIZ_COMPOSITOR;
29939   static constexpr auto CHROME_THREAD_COMPOSITOR_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR_WORKER;
29940   static constexpr auto CHROME_THREAD_SERVICE_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SERVICE_WORKER;
29941   static constexpr auto CHROME_THREAD_MEMORY_INFRA = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MEMORY_INFRA;
29942   static constexpr auto CHROME_THREAD_SAMPLING_PROFILER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SAMPLING_PROFILER;
29943   static constexpr auto ChromeThreadType_MIN = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_UNSPECIFIED;
29944   static constexpr auto ChromeThreadType_MAX = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SAMPLING_PROFILER;
29945   enum FieldNumbers {
29946     kPidFieldNumber = 1,
29947     kTidFieldNumber = 2,
29948     kThreadNameFieldNumber = 5,
29949     kChromeThreadTypeFieldNumber = 4,
29950     kReferenceTimestampUsFieldNumber = 6,
29951     kReferenceThreadTimeUsFieldNumber = 7,
29952     kReferenceThreadInstructionCountFieldNumber = 8,
29953     kLegacySortIndexFieldNumber = 3,
29954   };
29955 
29956   ThreadDescriptor();
29957   ~ThreadDescriptor() override;
29958   ThreadDescriptor(ThreadDescriptor&&) noexcept;
29959   ThreadDescriptor& operator=(ThreadDescriptor&&);
29960   ThreadDescriptor(const ThreadDescriptor&);
29961   ThreadDescriptor& operator=(const ThreadDescriptor&);
29962   bool operator==(const ThreadDescriptor&) const;
operator !=(const ThreadDescriptor & other) const29963   bool operator!=(const ThreadDescriptor& other) const { return !(*this == other); }
29964 
29965   bool ParseFromArray(const void*, size_t) override;
29966   std::string SerializeAsString() const override;
29967   std::vector<uint8_t> SerializeAsArray() const override;
29968   void Serialize(::protozero::Message*) const;
29969 
has_pid() const29970   bool has_pid() const { return _has_field_[1]; }
pid() const29971   int32_t pid() const { return pid_; }
set_pid(int32_t value)29972   void set_pid(int32_t value) { pid_ = value; _has_field_.set(1); }
29973 
has_tid() const29974   bool has_tid() const { return _has_field_[2]; }
tid() const29975   int32_t tid() const { return tid_; }
set_tid(int32_t value)29976   void set_tid(int32_t value) { tid_ = value; _has_field_.set(2); }
29977 
has_thread_name() const29978   bool has_thread_name() const { return _has_field_[5]; }
thread_name() const29979   const std::string& thread_name() const { return thread_name_; }
set_thread_name(const std::string & value)29980   void set_thread_name(const std::string& value) { thread_name_ = value; _has_field_.set(5); }
29981 
has_chrome_thread_type() const29982   bool has_chrome_thread_type() const { return _has_field_[4]; }
chrome_thread_type() const29983   ThreadDescriptor_ChromeThreadType chrome_thread_type() const { return chrome_thread_type_; }
set_chrome_thread_type(ThreadDescriptor_ChromeThreadType value)29984   void set_chrome_thread_type(ThreadDescriptor_ChromeThreadType value) { chrome_thread_type_ = value; _has_field_.set(4); }
29985 
has_reference_timestamp_us() const29986   bool has_reference_timestamp_us() const { return _has_field_[6]; }
reference_timestamp_us() const29987   int64_t reference_timestamp_us() const { return reference_timestamp_us_; }
set_reference_timestamp_us(int64_t value)29988   void set_reference_timestamp_us(int64_t value) { reference_timestamp_us_ = value; _has_field_.set(6); }
29989 
has_reference_thread_time_us() const29990   bool has_reference_thread_time_us() const { return _has_field_[7]; }
reference_thread_time_us() const29991   int64_t reference_thread_time_us() const { return reference_thread_time_us_; }
set_reference_thread_time_us(int64_t value)29992   void set_reference_thread_time_us(int64_t value) { reference_thread_time_us_ = value; _has_field_.set(7); }
29993 
has_reference_thread_instruction_count() const29994   bool has_reference_thread_instruction_count() const { return _has_field_[8]; }
reference_thread_instruction_count() const29995   int64_t reference_thread_instruction_count() const { return reference_thread_instruction_count_; }
set_reference_thread_instruction_count(int64_t value)29996   void set_reference_thread_instruction_count(int64_t value) { reference_thread_instruction_count_ = value; _has_field_.set(8); }
29997 
has_legacy_sort_index() const29998   bool has_legacy_sort_index() const { return _has_field_[3]; }
legacy_sort_index() const29999   int32_t legacy_sort_index() const { return legacy_sort_index_; }
set_legacy_sort_index(int32_t value)30000   void set_legacy_sort_index(int32_t value) { legacy_sort_index_ = value; _has_field_.set(3); }
30001 
30002  private:
30003   int32_t pid_{};
30004   int32_t tid_{};
30005   std::string thread_name_{};
30006   ThreadDescriptor_ChromeThreadType chrome_thread_type_{};
30007   int64_t reference_timestamp_us_{};
30008   int64_t reference_thread_time_us_{};
30009   int64_t reference_thread_instruction_count_{};
30010   int32_t legacy_sort_index_{};
30011 
30012   // Allows to preserve unknown protobuf fields for compatibility
30013   // with future versions of .proto files.
30014   std::string unknown_fields_;
30015 
30016   std::bitset<9> _has_field_{};
30017 };
30018 
30019 }  // namespace perfetto
30020 }  // namespace protos
30021 }  // namespace gen
30022 
30023 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_THREAD_DESCRIPTOR_PROTO_CPP_H_
30024 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
30025 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
30026 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
30027 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
30028 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
30029 #if defined(__GNUC__) || defined(__clang__)
30030 #pragma GCC diagnostic push
30031 #pragma GCC diagnostic ignored "-Wfloat-equal"
30032 #endif
30033 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/thread_descriptor.gen.h"
30034 
30035 namespace perfetto {
30036 namespace protos {
30037 namespace gen {
30038 
30039 ThreadDescriptor::ThreadDescriptor() = default;
30040 ThreadDescriptor::~ThreadDescriptor() = default;
30041 ThreadDescriptor::ThreadDescriptor(const ThreadDescriptor&) = default;
30042 ThreadDescriptor& ThreadDescriptor::operator=(const ThreadDescriptor&) = default;
30043 ThreadDescriptor::ThreadDescriptor(ThreadDescriptor&&) noexcept = default;
30044 ThreadDescriptor& ThreadDescriptor::operator=(ThreadDescriptor&&) = default;
30045 
operator ==(const ThreadDescriptor & other) const30046 bool ThreadDescriptor::operator==(const ThreadDescriptor& other) const {
30047   return unknown_fields_ == other.unknown_fields_
30048    && pid_ == other.pid_
30049    && tid_ == other.tid_
30050    && thread_name_ == other.thread_name_
30051    && chrome_thread_type_ == other.chrome_thread_type_
30052    && reference_timestamp_us_ == other.reference_timestamp_us_
30053    && reference_thread_time_us_ == other.reference_thread_time_us_
30054    && reference_thread_instruction_count_ == other.reference_thread_instruction_count_
30055    && legacy_sort_index_ == other.legacy_sort_index_;
30056 }
30057 
ParseFromArray(const void * raw,size_t size)30058 bool ThreadDescriptor::ParseFromArray(const void* raw, size_t size) {
30059   unknown_fields_.clear();
30060   bool packed_error = false;
30061 
30062   ::protozero::ProtoDecoder dec(raw, size);
30063   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
30064     if (field.id() < _has_field_.size()) {
30065       _has_field_.set(field.id());
30066     }
30067     switch (field.id()) {
30068       case 1 /* pid */:
30069         field.get(&pid_);
30070         break;
30071       case 2 /* tid */:
30072         field.get(&tid_);
30073         break;
30074       case 5 /* thread_name */:
30075         field.get(&thread_name_);
30076         break;
30077       case 4 /* chrome_thread_type */:
30078         field.get(&chrome_thread_type_);
30079         break;
30080       case 6 /* reference_timestamp_us */:
30081         field.get(&reference_timestamp_us_);
30082         break;
30083       case 7 /* reference_thread_time_us */:
30084         field.get(&reference_thread_time_us_);
30085         break;
30086       case 8 /* reference_thread_instruction_count */:
30087         field.get(&reference_thread_instruction_count_);
30088         break;
30089       case 3 /* legacy_sort_index */:
30090         field.get(&legacy_sort_index_);
30091         break;
30092       default:
30093         field.SerializeAndAppendTo(&unknown_fields_);
30094         break;
30095     }
30096   }
30097   return !packed_error && !dec.bytes_left();
30098 }
30099 
SerializeAsString() const30100 std::string ThreadDescriptor::SerializeAsString() const {
30101   ::protozero::HeapBuffered<::protozero::Message> msg;
30102   Serialize(msg.get());
30103   return msg.SerializeAsString();
30104 }
30105 
SerializeAsArray() const30106 std::vector<uint8_t> ThreadDescriptor::SerializeAsArray() const {
30107   ::protozero::HeapBuffered<::protozero::Message> msg;
30108   Serialize(msg.get());
30109   return msg.SerializeAsArray();
30110 }
30111 
Serialize(::protozero::Message * msg) const30112 void ThreadDescriptor::Serialize(::protozero::Message* msg) const {
30113   // Field 1: pid
30114   if (_has_field_[1]) {
30115     msg->AppendVarInt(1, pid_);
30116   }
30117 
30118   // Field 2: tid
30119   if (_has_field_[2]) {
30120     msg->AppendVarInt(2, tid_);
30121   }
30122 
30123   // Field 5: thread_name
30124   if (_has_field_[5]) {
30125     msg->AppendString(5, thread_name_);
30126   }
30127 
30128   // Field 4: chrome_thread_type
30129   if (_has_field_[4]) {
30130     msg->AppendVarInt(4, chrome_thread_type_);
30131   }
30132 
30133   // Field 6: reference_timestamp_us
30134   if (_has_field_[6]) {
30135     msg->AppendVarInt(6, reference_timestamp_us_);
30136   }
30137 
30138   // Field 7: reference_thread_time_us
30139   if (_has_field_[7]) {
30140     msg->AppendVarInt(7, reference_thread_time_us_);
30141   }
30142 
30143   // Field 8: reference_thread_instruction_count
30144   if (_has_field_[8]) {
30145     msg->AppendVarInt(8, reference_thread_instruction_count_);
30146   }
30147 
30148   // Field 3: legacy_sort_index
30149   if (_has_field_[3]) {
30150     msg->AppendVarInt(3, legacy_sort_index_);
30151   }
30152 
30153   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
30154 }
30155 
30156 }  // namespace perfetto
30157 }  // namespace protos
30158 }  // namespace gen
30159 #if defined(__GNUC__) || defined(__clang__)
30160 #pragma GCC diagnostic pop
30161 #endif
30162 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/track_descriptor.gen.cc
30163 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
30164 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
30165 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
30166 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
30167 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
30168 #if defined(__GNUC__) || defined(__clang__)
30169 #pragma GCC diagnostic push
30170 #pragma GCC diagnostic ignored "-Wfloat-equal"
30171 #endif
30172 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_descriptor.gen.h"
30173 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/counter_descriptor.gen.h"
30174 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/thread_descriptor.gen.h"
30175 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/process_descriptor.gen.h"
30176 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_thread_descriptor.gen.h"
30177 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_process_descriptor.gen.h"
30178 
30179 namespace perfetto {
30180 namespace protos {
30181 namespace gen {
30182 
30183 TrackDescriptor::TrackDescriptor() = default;
30184 TrackDescriptor::~TrackDescriptor() = default;
30185 TrackDescriptor::TrackDescriptor(const TrackDescriptor&) = default;
30186 TrackDescriptor& TrackDescriptor::operator=(const TrackDescriptor&) = default;
30187 TrackDescriptor::TrackDescriptor(TrackDescriptor&&) noexcept = default;
30188 TrackDescriptor& TrackDescriptor::operator=(TrackDescriptor&&) = default;
30189 
operator ==(const TrackDescriptor & other) const30190 bool TrackDescriptor::operator==(const TrackDescriptor& other) const {
30191   return unknown_fields_ == other.unknown_fields_
30192    && uuid_ == other.uuid_
30193    && parent_uuid_ == other.parent_uuid_
30194    && name_ == other.name_
30195    && process_ == other.process_
30196    && chrome_process_ == other.chrome_process_
30197    && thread_ == other.thread_
30198    && chrome_thread_ == other.chrome_thread_
30199    && counter_ == other.counter_;
30200 }
30201 
ParseFromArray(const void * raw,size_t size)30202 bool TrackDescriptor::ParseFromArray(const void* raw, size_t size) {
30203   unknown_fields_.clear();
30204   bool packed_error = false;
30205 
30206   ::protozero::ProtoDecoder dec(raw, size);
30207   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
30208     if (field.id() < _has_field_.size()) {
30209       _has_field_.set(field.id());
30210     }
30211     switch (field.id()) {
30212       case 1 /* uuid */:
30213         field.get(&uuid_);
30214         break;
30215       case 5 /* parent_uuid */:
30216         field.get(&parent_uuid_);
30217         break;
30218       case 2 /* name */:
30219         field.get(&name_);
30220         break;
30221       case 3 /* process */:
30222         (*process_).ParseFromArray(field.data(), field.size());
30223         break;
30224       case 6 /* chrome_process */:
30225         (*chrome_process_).ParseFromArray(field.data(), field.size());
30226         break;
30227       case 4 /* thread */:
30228         (*thread_).ParseFromArray(field.data(), field.size());
30229         break;
30230       case 7 /* chrome_thread */:
30231         (*chrome_thread_).ParseFromArray(field.data(), field.size());
30232         break;
30233       case 8 /* counter */:
30234         (*counter_).ParseFromArray(field.data(), field.size());
30235         break;
30236       default:
30237         field.SerializeAndAppendTo(&unknown_fields_);
30238         break;
30239     }
30240   }
30241   return !packed_error && !dec.bytes_left();
30242 }
30243 
SerializeAsString() const30244 std::string TrackDescriptor::SerializeAsString() const {
30245   ::protozero::HeapBuffered<::protozero::Message> msg;
30246   Serialize(msg.get());
30247   return msg.SerializeAsString();
30248 }
30249 
SerializeAsArray() const30250 std::vector<uint8_t> TrackDescriptor::SerializeAsArray() const {
30251   ::protozero::HeapBuffered<::protozero::Message> msg;
30252   Serialize(msg.get());
30253   return msg.SerializeAsArray();
30254 }
30255 
Serialize(::protozero::Message * msg) const30256 void TrackDescriptor::Serialize(::protozero::Message* msg) const {
30257   // Field 1: uuid
30258   if (_has_field_[1]) {
30259     msg->AppendVarInt(1, uuid_);
30260   }
30261 
30262   // Field 5: parent_uuid
30263   if (_has_field_[5]) {
30264     msg->AppendVarInt(5, parent_uuid_);
30265   }
30266 
30267   // Field 2: name
30268   if (_has_field_[2]) {
30269     msg->AppendString(2, name_);
30270   }
30271 
30272   // Field 3: process
30273   if (_has_field_[3]) {
30274     (*process_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
30275   }
30276 
30277   // Field 6: chrome_process
30278   if (_has_field_[6]) {
30279     (*chrome_process_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
30280   }
30281 
30282   // Field 4: thread
30283   if (_has_field_[4]) {
30284     (*thread_).Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
30285   }
30286 
30287   // Field 7: chrome_thread
30288   if (_has_field_[7]) {
30289     (*chrome_thread_).Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
30290   }
30291 
30292   // Field 8: counter
30293   if (_has_field_[8]) {
30294     (*counter_).Serialize(msg->BeginNestedMessage<::protozero::Message>(8));
30295   }
30296 
30297   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
30298 }
30299 
30300 }  // namespace perfetto
30301 }  // namespace protos
30302 }  // namespace gen
30303 #if defined(__GNUC__) || defined(__clang__)
30304 #pragma GCC diagnostic pop
30305 #endif
30306 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/track_event.gen.cc
30307 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/track_event.gen.h
30308 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
30309 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TRACK_EVENT_PROTO_CPP_H_
30310 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TRACK_EVENT_PROTO_CPP_H_
30311 
30312 #include <stdint.h>
30313 #include <bitset>
30314 #include <vector>
30315 #include <string>
30316 #include <type_traits>
30317 
30318 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
30319 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
30320 // gen_amalgamated expanded: #include "perfetto/base/export.h"
30321 
30322 namespace perfetto {
30323 namespace protos {
30324 namespace gen {
30325 class EventName;
30326 class EventCategory;
30327 class TrackEventDefaults;
30328 class TrackEvent;
30329 class TrackEvent_LegacyEvent;
30330 class ChromeMojoEventInfo;
30331 class ChromeMessagePump;
30332 class SourceLocation;
30333 class ChromeContentSettingsEventInfo;
30334 class ChromeWindowHandleEventInfo;
30335 class ChromeRendererSchedulerState;
30336 class ChromeApplicationStateInfo;
30337 class ChromeFrameReporter;
30338 class ChromeLatencyInfo;
30339 class ChromeLatencyInfo_ComponentInfo;
30340 class ChromeHistogramSample;
30341 class ChromeLegacyIpc;
30342 class ChromeKeyedService;
30343 class ChromeUserEvent;
30344 class ChromeCompositorSchedulerState;
30345 class CompositorTimingHistory;
30346 class BeginFrameSourceState;
30347 class BeginFrameArgs;
30348 class BeginFrameObserverState;
30349 class BeginImplFrameArgs;
30350 class BeginImplFrameArgs_TimestampsInUs;
30351 class ChromeCompositorStateMachine;
30352 class ChromeCompositorStateMachine_MinorState;
30353 class ChromeCompositorStateMachine_MajorState;
30354 class LogMessage;
30355 class TaskExecution;
30356 class DebugAnnotation;
30357 class DebugAnnotation_NestedValue;
30358 enum TrackEvent_Type : int;
30359 enum TrackEvent_LegacyEvent_FlowDirection : int;
30360 enum TrackEvent_LegacyEvent_InstantEventScope : int;
30361 enum ChromeRAILMode : int;
30362 enum ChromeApplicationStateInfo_ChromeApplicationState : int;
30363 enum ChromeFrameReporter_State : int;
30364 enum ChromeFrameReporter_FrameDropReason : int;
30365 enum ChromeFrameReporter_ScrollState : int;
30366 enum ChromeLatencyInfo_Step : int;
30367 enum ChromeLatencyInfo_LatencyComponentType : int;
30368 enum ChromeLegacyIpc_MessageClass : int;
30369 enum ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode : int;
30370 enum ChromeCompositorSchedulerAction : int;
30371 enum BeginFrameArgs_BeginFrameArgsType : int;
30372 enum BeginImplFrameArgs_State : int;
30373 enum ChromeCompositorStateMachine_MinorState_TreePriority : int;
30374 enum ChromeCompositorStateMachine_MinorState_ScrollHandlerState : int;
30375 enum ChromeCompositorStateMachine_MajorState_BeginImplFrameState : int;
30376 enum ChromeCompositorStateMachine_MajorState_BeginMainFrameState : int;
30377 enum ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState : int;
30378 enum ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState : int;
30379 enum DebugAnnotation_NestedValue_NestedType : int;
30380 }  // namespace perfetto
30381 }  // namespace protos
30382 }  // namespace gen
30383 
30384 namespace protozero {
30385 class Message;
30386 }  // namespace protozero
30387 
30388 namespace perfetto {
30389 namespace protos {
30390 namespace gen {
30391 enum TrackEvent_Type : int {
30392   TrackEvent_Type_TYPE_UNSPECIFIED = 0,
30393   TrackEvent_Type_TYPE_SLICE_BEGIN = 1,
30394   TrackEvent_Type_TYPE_SLICE_END = 2,
30395   TrackEvent_Type_TYPE_INSTANT = 3,
30396   TrackEvent_Type_TYPE_COUNTER = 4,
30397 };
30398 enum TrackEvent_LegacyEvent_FlowDirection : int {
30399   TrackEvent_LegacyEvent_FlowDirection_FLOW_UNSPECIFIED = 0,
30400   TrackEvent_LegacyEvent_FlowDirection_FLOW_IN = 1,
30401   TrackEvent_LegacyEvent_FlowDirection_FLOW_OUT = 2,
30402   TrackEvent_LegacyEvent_FlowDirection_FLOW_INOUT = 3,
30403 };
30404 enum TrackEvent_LegacyEvent_InstantEventScope : int {
30405   TrackEvent_LegacyEvent_InstantEventScope_SCOPE_UNSPECIFIED = 0,
30406   TrackEvent_LegacyEvent_InstantEventScope_SCOPE_GLOBAL = 1,
30407   TrackEvent_LegacyEvent_InstantEventScope_SCOPE_PROCESS = 2,
30408   TrackEvent_LegacyEvent_InstantEventScope_SCOPE_THREAD = 3,
30409 };
30410 
30411 class PERFETTO_EXPORT EventName : public ::protozero::CppMessageObj {
30412  public:
30413   enum FieldNumbers {
30414     kIidFieldNumber = 1,
30415     kNameFieldNumber = 2,
30416   };
30417 
30418   EventName();
30419   ~EventName() override;
30420   EventName(EventName&&) noexcept;
30421   EventName& operator=(EventName&&);
30422   EventName(const EventName&);
30423   EventName& operator=(const EventName&);
30424   bool operator==(const EventName&) const;
operator !=(const EventName & other) const30425   bool operator!=(const EventName& other) const { return !(*this == other); }
30426 
30427   bool ParseFromArray(const void*, size_t) override;
30428   std::string SerializeAsString() const override;
30429   std::vector<uint8_t> SerializeAsArray() const override;
30430   void Serialize(::protozero::Message*) const;
30431 
has_iid() const30432   bool has_iid() const { return _has_field_[1]; }
iid() const30433   uint64_t iid() const { return iid_; }
set_iid(uint64_t value)30434   void set_iid(uint64_t value) { iid_ = value; _has_field_.set(1); }
30435 
has_name() const30436   bool has_name() const { return _has_field_[2]; }
name() const30437   const std::string& name() const { return name_; }
set_name(const std::string & value)30438   void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
30439 
30440  private:
30441   uint64_t iid_{};
30442   std::string name_{};
30443 
30444   // Allows to preserve unknown protobuf fields for compatibility
30445   // with future versions of .proto files.
30446   std::string unknown_fields_;
30447 
30448   std::bitset<3> _has_field_{};
30449 };
30450 
30451 
30452 class PERFETTO_EXPORT EventCategory : public ::protozero::CppMessageObj {
30453  public:
30454   enum FieldNumbers {
30455     kIidFieldNumber = 1,
30456     kNameFieldNumber = 2,
30457   };
30458 
30459   EventCategory();
30460   ~EventCategory() override;
30461   EventCategory(EventCategory&&) noexcept;
30462   EventCategory& operator=(EventCategory&&);
30463   EventCategory(const EventCategory&);
30464   EventCategory& operator=(const EventCategory&);
30465   bool operator==(const EventCategory&) const;
operator !=(const EventCategory & other) const30466   bool operator!=(const EventCategory& other) const { return !(*this == other); }
30467 
30468   bool ParseFromArray(const void*, size_t) override;
30469   std::string SerializeAsString() const override;
30470   std::vector<uint8_t> SerializeAsArray() const override;
30471   void Serialize(::protozero::Message*) const;
30472 
has_iid() const30473   bool has_iid() const { return _has_field_[1]; }
iid() const30474   uint64_t iid() const { return iid_; }
set_iid(uint64_t value)30475   void set_iid(uint64_t value) { iid_ = value; _has_field_.set(1); }
30476 
has_name() const30477   bool has_name() const { return _has_field_[2]; }
name() const30478   const std::string& name() const { return name_; }
set_name(const std::string & value)30479   void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
30480 
30481  private:
30482   uint64_t iid_{};
30483   std::string name_{};
30484 
30485   // Allows to preserve unknown protobuf fields for compatibility
30486   // with future versions of .proto files.
30487   std::string unknown_fields_;
30488 
30489   std::bitset<3> _has_field_{};
30490 };
30491 
30492 
30493 class PERFETTO_EXPORT TrackEventDefaults : public ::protozero::CppMessageObj {
30494  public:
30495   enum FieldNumbers {
30496     kTrackUuidFieldNumber = 11,
30497     kExtraCounterTrackUuidsFieldNumber = 31,
30498     kExtraDoubleCounterTrackUuidsFieldNumber = 45,
30499   };
30500 
30501   TrackEventDefaults();
30502   ~TrackEventDefaults() override;
30503   TrackEventDefaults(TrackEventDefaults&&) noexcept;
30504   TrackEventDefaults& operator=(TrackEventDefaults&&);
30505   TrackEventDefaults(const TrackEventDefaults&);
30506   TrackEventDefaults& operator=(const TrackEventDefaults&);
30507   bool operator==(const TrackEventDefaults&) const;
operator !=(const TrackEventDefaults & other) const30508   bool operator!=(const TrackEventDefaults& other) const { return !(*this == other); }
30509 
30510   bool ParseFromArray(const void*, size_t) override;
30511   std::string SerializeAsString() const override;
30512   std::vector<uint8_t> SerializeAsArray() const override;
30513   void Serialize(::protozero::Message*) const;
30514 
has_track_uuid() const30515   bool has_track_uuid() const { return _has_field_[11]; }
track_uuid() const30516   uint64_t track_uuid() const { return track_uuid_; }
set_track_uuid(uint64_t value)30517   void set_track_uuid(uint64_t value) { track_uuid_ = value; _has_field_.set(11); }
30518 
extra_counter_track_uuids() const30519   const std::vector<uint64_t>& extra_counter_track_uuids() const { return extra_counter_track_uuids_; }
mutable_extra_counter_track_uuids()30520   std::vector<uint64_t>* mutable_extra_counter_track_uuids() { return &extra_counter_track_uuids_; }
extra_counter_track_uuids_size() const30521   int extra_counter_track_uuids_size() const { return static_cast<int>(extra_counter_track_uuids_.size()); }
clear_extra_counter_track_uuids()30522   void clear_extra_counter_track_uuids() { extra_counter_track_uuids_.clear(); }
add_extra_counter_track_uuids(uint64_t value)30523   void add_extra_counter_track_uuids(uint64_t value) { extra_counter_track_uuids_.emplace_back(value); }
add_extra_counter_track_uuids()30524   uint64_t* add_extra_counter_track_uuids() { extra_counter_track_uuids_.emplace_back(); return &extra_counter_track_uuids_.back(); }
30525 
extra_double_counter_track_uuids() const30526   const std::vector<uint64_t>& extra_double_counter_track_uuids() const { return extra_double_counter_track_uuids_; }
mutable_extra_double_counter_track_uuids()30527   std::vector<uint64_t>* mutable_extra_double_counter_track_uuids() { return &extra_double_counter_track_uuids_; }
extra_double_counter_track_uuids_size() const30528   int extra_double_counter_track_uuids_size() const { return static_cast<int>(extra_double_counter_track_uuids_.size()); }
clear_extra_double_counter_track_uuids()30529   void clear_extra_double_counter_track_uuids() { extra_double_counter_track_uuids_.clear(); }
add_extra_double_counter_track_uuids(uint64_t value)30530   void add_extra_double_counter_track_uuids(uint64_t value) { extra_double_counter_track_uuids_.emplace_back(value); }
add_extra_double_counter_track_uuids()30531   uint64_t* add_extra_double_counter_track_uuids() { extra_double_counter_track_uuids_.emplace_back(); return &extra_double_counter_track_uuids_.back(); }
30532 
30533  private:
30534   uint64_t track_uuid_{};
30535   std::vector<uint64_t> extra_counter_track_uuids_;
30536   std::vector<uint64_t> extra_double_counter_track_uuids_;
30537 
30538   // Allows to preserve unknown protobuf fields for compatibility
30539   // with future versions of .proto files.
30540   std::string unknown_fields_;
30541 
30542   std::bitset<46> _has_field_{};
30543 };
30544 
30545 
30546 class PERFETTO_EXPORT TrackEvent : public ::protozero::CppMessageObj {
30547  public:
30548   using LegacyEvent = TrackEvent_LegacyEvent;
30549   using Type = TrackEvent_Type;
30550   static constexpr auto TYPE_UNSPECIFIED = TrackEvent_Type_TYPE_UNSPECIFIED;
30551   static constexpr auto TYPE_SLICE_BEGIN = TrackEvent_Type_TYPE_SLICE_BEGIN;
30552   static constexpr auto TYPE_SLICE_END = TrackEvent_Type_TYPE_SLICE_END;
30553   static constexpr auto TYPE_INSTANT = TrackEvent_Type_TYPE_INSTANT;
30554   static constexpr auto TYPE_COUNTER = TrackEvent_Type_TYPE_COUNTER;
30555   static constexpr auto Type_MIN = TrackEvent_Type_TYPE_UNSPECIFIED;
30556   static constexpr auto Type_MAX = TrackEvent_Type_TYPE_COUNTER;
30557   enum FieldNumbers {
30558     kCategoryIidsFieldNumber = 3,
30559     kCategoriesFieldNumber = 22,
30560     kNameIidFieldNumber = 10,
30561     kNameFieldNumber = 23,
30562     kTypeFieldNumber = 9,
30563     kTrackUuidFieldNumber = 11,
30564     kCounterValueFieldNumber = 30,
30565     kDoubleCounterValueFieldNumber = 44,
30566     kExtraCounterTrackUuidsFieldNumber = 31,
30567     kExtraCounterValuesFieldNumber = 12,
30568     kExtraDoubleCounterTrackUuidsFieldNumber = 45,
30569     kExtraDoubleCounterValuesFieldNumber = 46,
30570     kFlowIdsFieldNumber = 36,
30571     kTerminatingFlowIdsFieldNumber = 42,
30572     kDebugAnnotationsFieldNumber = 4,
30573     kTaskExecutionFieldNumber = 5,
30574     kLogMessageFieldNumber = 21,
30575     kCcSchedulerStateFieldNumber = 24,
30576     kChromeUserEventFieldNumber = 25,
30577     kChromeKeyedServiceFieldNumber = 26,
30578     kChromeLegacyIpcFieldNumber = 27,
30579     kChromeHistogramSampleFieldNumber = 28,
30580     kChromeLatencyInfoFieldNumber = 29,
30581     kChromeFrameReporterFieldNumber = 32,
30582     kChromeApplicationStateInfoFieldNumber = 39,
30583     kChromeRendererSchedulerStateFieldNumber = 40,
30584     kChromeWindowHandleEventInfoFieldNumber = 41,
30585     kChromeContentSettingsEventInfoFieldNumber = 43,
30586     kSourceLocationFieldNumber = 33,
30587     kSourceLocationIidFieldNumber = 34,
30588     kChromeMessagePumpFieldNumber = 35,
30589     kChromeMojoEventInfoFieldNumber = 38,
30590     kTimestampDeltaUsFieldNumber = 1,
30591     kTimestampAbsoluteUsFieldNumber = 16,
30592     kThreadTimeDeltaUsFieldNumber = 2,
30593     kThreadTimeAbsoluteUsFieldNumber = 17,
30594     kThreadInstructionCountDeltaFieldNumber = 8,
30595     kThreadInstructionCountAbsoluteFieldNumber = 20,
30596     kLegacyEventFieldNumber = 6,
30597   };
30598 
30599   TrackEvent();
30600   ~TrackEvent() override;
30601   TrackEvent(TrackEvent&&) noexcept;
30602   TrackEvent& operator=(TrackEvent&&);
30603   TrackEvent(const TrackEvent&);
30604   TrackEvent& operator=(const TrackEvent&);
30605   bool operator==(const TrackEvent&) const;
operator !=(const TrackEvent & other) const30606   bool operator!=(const TrackEvent& other) const { return !(*this == other); }
30607 
30608   bool ParseFromArray(const void*, size_t) override;
30609   std::string SerializeAsString() const override;
30610   std::vector<uint8_t> SerializeAsArray() const override;
30611   void Serialize(::protozero::Message*) const;
30612 
category_iids() const30613   const std::vector<uint64_t>& category_iids() const { return category_iids_; }
mutable_category_iids()30614   std::vector<uint64_t>* mutable_category_iids() { return &category_iids_; }
category_iids_size() const30615   int category_iids_size() const { return static_cast<int>(category_iids_.size()); }
clear_category_iids()30616   void clear_category_iids() { category_iids_.clear(); }
add_category_iids(uint64_t value)30617   void add_category_iids(uint64_t value) { category_iids_.emplace_back(value); }
add_category_iids()30618   uint64_t* add_category_iids() { category_iids_.emplace_back(); return &category_iids_.back(); }
30619 
categories() const30620   const std::vector<std::string>& categories() const { return categories_; }
mutable_categories()30621   std::vector<std::string>* mutable_categories() { return &categories_; }
categories_size() const30622   int categories_size() const { return static_cast<int>(categories_.size()); }
clear_categories()30623   void clear_categories() { categories_.clear(); }
add_categories(std::string value)30624   void add_categories(std::string value) { categories_.emplace_back(value); }
add_categories()30625   std::string* add_categories() { categories_.emplace_back(); return &categories_.back(); }
30626 
has_name_iid() const30627   bool has_name_iid() const { return _has_field_[10]; }
name_iid() const30628   uint64_t name_iid() const { return name_iid_; }
set_name_iid(uint64_t value)30629   void set_name_iid(uint64_t value) { name_iid_ = value; _has_field_.set(10); }
30630 
has_name() const30631   bool has_name() const { return _has_field_[23]; }
name() const30632   const std::string& name() const { return name_; }
set_name(const std::string & value)30633   void set_name(const std::string& value) { name_ = value; _has_field_.set(23); }
30634 
has_type() const30635   bool has_type() const { return _has_field_[9]; }
type() const30636   TrackEvent_Type type() const { return type_; }
set_type(TrackEvent_Type value)30637   void set_type(TrackEvent_Type value) { type_ = value; _has_field_.set(9); }
30638 
has_track_uuid() const30639   bool has_track_uuid() const { return _has_field_[11]; }
track_uuid() const30640   uint64_t track_uuid() const { return track_uuid_; }
set_track_uuid(uint64_t value)30641   void set_track_uuid(uint64_t value) { track_uuid_ = value; _has_field_.set(11); }
30642 
has_counter_value() const30643   bool has_counter_value() const { return _has_field_[30]; }
counter_value() const30644   int64_t counter_value() const { return counter_value_; }
set_counter_value(int64_t value)30645   void set_counter_value(int64_t value) { counter_value_ = value; _has_field_.set(30); }
30646 
has_double_counter_value() const30647   bool has_double_counter_value() const { return _has_field_[44]; }
double_counter_value() const30648   double double_counter_value() const { return double_counter_value_; }
set_double_counter_value(double value)30649   void set_double_counter_value(double value) { double_counter_value_ = value; _has_field_.set(44); }
30650 
extra_counter_track_uuids() const30651   const std::vector<uint64_t>& extra_counter_track_uuids() const { return extra_counter_track_uuids_; }
mutable_extra_counter_track_uuids()30652   std::vector<uint64_t>* mutable_extra_counter_track_uuids() { return &extra_counter_track_uuids_; }
extra_counter_track_uuids_size() const30653   int extra_counter_track_uuids_size() const { return static_cast<int>(extra_counter_track_uuids_.size()); }
clear_extra_counter_track_uuids()30654   void clear_extra_counter_track_uuids() { extra_counter_track_uuids_.clear(); }
add_extra_counter_track_uuids(uint64_t value)30655   void add_extra_counter_track_uuids(uint64_t value) { extra_counter_track_uuids_.emplace_back(value); }
add_extra_counter_track_uuids()30656   uint64_t* add_extra_counter_track_uuids() { extra_counter_track_uuids_.emplace_back(); return &extra_counter_track_uuids_.back(); }
30657 
extra_counter_values() const30658   const std::vector<int64_t>& extra_counter_values() const { return extra_counter_values_; }
mutable_extra_counter_values()30659   std::vector<int64_t>* mutable_extra_counter_values() { return &extra_counter_values_; }
extra_counter_values_size() const30660   int extra_counter_values_size() const { return static_cast<int>(extra_counter_values_.size()); }
clear_extra_counter_values()30661   void clear_extra_counter_values() { extra_counter_values_.clear(); }
add_extra_counter_values(int64_t value)30662   void add_extra_counter_values(int64_t value) { extra_counter_values_.emplace_back(value); }
add_extra_counter_values()30663   int64_t* add_extra_counter_values() { extra_counter_values_.emplace_back(); return &extra_counter_values_.back(); }
30664 
extra_double_counter_track_uuids() const30665   const std::vector<uint64_t>& extra_double_counter_track_uuids() const { return extra_double_counter_track_uuids_; }
mutable_extra_double_counter_track_uuids()30666   std::vector<uint64_t>* mutable_extra_double_counter_track_uuids() { return &extra_double_counter_track_uuids_; }
extra_double_counter_track_uuids_size() const30667   int extra_double_counter_track_uuids_size() const { return static_cast<int>(extra_double_counter_track_uuids_.size()); }
clear_extra_double_counter_track_uuids()30668   void clear_extra_double_counter_track_uuids() { extra_double_counter_track_uuids_.clear(); }
add_extra_double_counter_track_uuids(uint64_t value)30669   void add_extra_double_counter_track_uuids(uint64_t value) { extra_double_counter_track_uuids_.emplace_back(value); }
add_extra_double_counter_track_uuids()30670   uint64_t* add_extra_double_counter_track_uuids() { extra_double_counter_track_uuids_.emplace_back(); return &extra_double_counter_track_uuids_.back(); }
30671 
extra_double_counter_values() const30672   const std::vector<double>& extra_double_counter_values() const { return extra_double_counter_values_; }
mutable_extra_double_counter_values()30673   std::vector<double>* mutable_extra_double_counter_values() { return &extra_double_counter_values_; }
extra_double_counter_values_size() const30674   int extra_double_counter_values_size() const { return static_cast<int>(extra_double_counter_values_.size()); }
clear_extra_double_counter_values()30675   void clear_extra_double_counter_values() { extra_double_counter_values_.clear(); }
add_extra_double_counter_values(double value)30676   void add_extra_double_counter_values(double value) { extra_double_counter_values_.emplace_back(value); }
add_extra_double_counter_values()30677   double* add_extra_double_counter_values() { extra_double_counter_values_.emplace_back(); return &extra_double_counter_values_.back(); }
30678 
flow_ids() const30679   const std::vector<uint64_t>& flow_ids() const { return flow_ids_; }
mutable_flow_ids()30680   std::vector<uint64_t>* mutable_flow_ids() { return &flow_ids_; }
flow_ids_size() const30681   int flow_ids_size() const { return static_cast<int>(flow_ids_.size()); }
clear_flow_ids()30682   void clear_flow_ids() { flow_ids_.clear(); }
add_flow_ids(uint64_t value)30683   void add_flow_ids(uint64_t value) { flow_ids_.emplace_back(value); }
add_flow_ids()30684   uint64_t* add_flow_ids() { flow_ids_.emplace_back(); return &flow_ids_.back(); }
30685 
terminating_flow_ids() const30686   const std::vector<uint64_t>& terminating_flow_ids() const { return terminating_flow_ids_; }
mutable_terminating_flow_ids()30687   std::vector<uint64_t>* mutable_terminating_flow_ids() { return &terminating_flow_ids_; }
terminating_flow_ids_size() const30688   int terminating_flow_ids_size() const { return static_cast<int>(terminating_flow_ids_.size()); }
clear_terminating_flow_ids()30689   void clear_terminating_flow_ids() { terminating_flow_ids_.clear(); }
add_terminating_flow_ids(uint64_t value)30690   void add_terminating_flow_ids(uint64_t value) { terminating_flow_ids_.emplace_back(value); }
add_terminating_flow_ids()30691   uint64_t* add_terminating_flow_ids() { terminating_flow_ids_.emplace_back(); return &terminating_flow_ids_.back(); }
30692 
debug_annotations() const30693   const std::vector<DebugAnnotation>& debug_annotations() const { return debug_annotations_; }
mutable_debug_annotations()30694   std::vector<DebugAnnotation>* mutable_debug_annotations() { return &debug_annotations_; }
30695   int debug_annotations_size() const;
30696   void clear_debug_annotations();
30697   DebugAnnotation* add_debug_annotations();
30698 
has_task_execution() const30699   bool has_task_execution() const { return _has_field_[5]; }
task_execution() const30700   const TaskExecution& task_execution() const { return *task_execution_; }
mutable_task_execution()30701   TaskExecution* mutable_task_execution() { _has_field_.set(5); return task_execution_.get(); }
30702 
has_log_message() const30703   bool has_log_message() const { return _has_field_[21]; }
log_message() const30704   const LogMessage& log_message() const { return *log_message_; }
mutable_log_message()30705   LogMessage* mutable_log_message() { _has_field_.set(21); return log_message_.get(); }
30706 
has_cc_scheduler_state() const30707   bool has_cc_scheduler_state() const { return _has_field_[24]; }
cc_scheduler_state() const30708   const ChromeCompositorSchedulerState& cc_scheduler_state() const { return *cc_scheduler_state_; }
mutable_cc_scheduler_state()30709   ChromeCompositorSchedulerState* mutable_cc_scheduler_state() { _has_field_.set(24); return cc_scheduler_state_.get(); }
30710 
has_chrome_user_event() const30711   bool has_chrome_user_event() const { return _has_field_[25]; }
chrome_user_event() const30712   const ChromeUserEvent& chrome_user_event() const { return *chrome_user_event_; }
mutable_chrome_user_event()30713   ChromeUserEvent* mutable_chrome_user_event() { _has_field_.set(25); return chrome_user_event_.get(); }
30714 
has_chrome_keyed_service() const30715   bool has_chrome_keyed_service() const { return _has_field_[26]; }
chrome_keyed_service() const30716   const ChromeKeyedService& chrome_keyed_service() const { return *chrome_keyed_service_; }
mutable_chrome_keyed_service()30717   ChromeKeyedService* mutable_chrome_keyed_service() { _has_field_.set(26); return chrome_keyed_service_.get(); }
30718 
has_chrome_legacy_ipc() const30719   bool has_chrome_legacy_ipc() const { return _has_field_[27]; }
chrome_legacy_ipc() const30720   const ChromeLegacyIpc& chrome_legacy_ipc() const { return *chrome_legacy_ipc_; }
mutable_chrome_legacy_ipc()30721   ChromeLegacyIpc* mutable_chrome_legacy_ipc() { _has_field_.set(27); return chrome_legacy_ipc_.get(); }
30722 
has_chrome_histogram_sample() const30723   bool has_chrome_histogram_sample() const { return _has_field_[28]; }
chrome_histogram_sample() const30724   const ChromeHistogramSample& chrome_histogram_sample() const { return *chrome_histogram_sample_; }
mutable_chrome_histogram_sample()30725   ChromeHistogramSample* mutable_chrome_histogram_sample() { _has_field_.set(28); return chrome_histogram_sample_.get(); }
30726 
has_chrome_latency_info() const30727   bool has_chrome_latency_info() const { return _has_field_[29]; }
chrome_latency_info() const30728   const ChromeLatencyInfo& chrome_latency_info() const { return *chrome_latency_info_; }
mutable_chrome_latency_info()30729   ChromeLatencyInfo* mutable_chrome_latency_info() { _has_field_.set(29); return chrome_latency_info_.get(); }
30730 
has_chrome_frame_reporter() const30731   bool has_chrome_frame_reporter() const { return _has_field_[32]; }
chrome_frame_reporter() const30732   const ChromeFrameReporter& chrome_frame_reporter() const { return *chrome_frame_reporter_; }
mutable_chrome_frame_reporter()30733   ChromeFrameReporter* mutable_chrome_frame_reporter() { _has_field_.set(32); return chrome_frame_reporter_.get(); }
30734 
has_chrome_application_state_info() const30735   bool has_chrome_application_state_info() const { return _has_field_[39]; }
chrome_application_state_info() const30736   const ChromeApplicationStateInfo& chrome_application_state_info() const { return *chrome_application_state_info_; }
mutable_chrome_application_state_info()30737   ChromeApplicationStateInfo* mutable_chrome_application_state_info() { _has_field_.set(39); return chrome_application_state_info_.get(); }
30738 
has_chrome_renderer_scheduler_state() const30739   bool has_chrome_renderer_scheduler_state() const { return _has_field_[40]; }
chrome_renderer_scheduler_state() const30740   const ChromeRendererSchedulerState& chrome_renderer_scheduler_state() const { return *chrome_renderer_scheduler_state_; }
mutable_chrome_renderer_scheduler_state()30741   ChromeRendererSchedulerState* mutable_chrome_renderer_scheduler_state() { _has_field_.set(40); return chrome_renderer_scheduler_state_.get(); }
30742 
has_chrome_window_handle_event_info() const30743   bool has_chrome_window_handle_event_info() const { return _has_field_[41]; }
chrome_window_handle_event_info() const30744   const ChromeWindowHandleEventInfo& chrome_window_handle_event_info() const { return *chrome_window_handle_event_info_; }
mutable_chrome_window_handle_event_info()30745   ChromeWindowHandleEventInfo* mutable_chrome_window_handle_event_info() { _has_field_.set(41); return chrome_window_handle_event_info_.get(); }
30746 
has_chrome_content_settings_event_info() const30747   bool has_chrome_content_settings_event_info() const { return _has_field_[43]; }
chrome_content_settings_event_info() const30748   const ChromeContentSettingsEventInfo& chrome_content_settings_event_info() const { return *chrome_content_settings_event_info_; }
mutable_chrome_content_settings_event_info()30749   ChromeContentSettingsEventInfo* mutable_chrome_content_settings_event_info() { _has_field_.set(43); return chrome_content_settings_event_info_.get(); }
30750 
has_source_location() const30751   bool has_source_location() const { return _has_field_[33]; }
source_location() const30752   const SourceLocation& source_location() const { return *source_location_; }
mutable_source_location()30753   SourceLocation* mutable_source_location() { _has_field_.set(33); return source_location_.get(); }
30754 
has_source_location_iid() const30755   bool has_source_location_iid() const { return _has_field_[34]; }
source_location_iid() const30756   uint64_t source_location_iid() const { return source_location_iid_; }
set_source_location_iid(uint64_t value)30757   void set_source_location_iid(uint64_t value) { source_location_iid_ = value; _has_field_.set(34); }
30758 
has_chrome_message_pump() const30759   bool has_chrome_message_pump() const { return _has_field_[35]; }
chrome_message_pump() const30760   const ChromeMessagePump& chrome_message_pump() const { return *chrome_message_pump_; }
mutable_chrome_message_pump()30761   ChromeMessagePump* mutable_chrome_message_pump() { _has_field_.set(35); return chrome_message_pump_.get(); }
30762 
has_chrome_mojo_event_info() const30763   bool has_chrome_mojo_event_info() const { return _has_field_[38]; }
chrome_mojo_event_info() const30764   const ChromeMojoEventInfo& chrome_mojo_event_info() const { return *chrome_mojo_event_info_; }
mutable_chrome_mojo_event_info()30765   ChromeMojoEventInfo* mutable_chrome_mojo_event_info() { _has_field_.set(38); return chrome_mojo_event_info_.get(); }
30766 
has_timestamp_delta_us() const30767   bool has_timestamp_delta_us() const { return _has_field_[1]; }
timestamp_delta_us() const30768   int64_t timestamp_delta_us() const { return timestamp_delta_us_; }
set_timestamp_delta_us(int64_t value)30769   void set_timestamp_delta_us(int64_t value) { timestamp_delta_us_ = value; _has_field_.set(1); }
30770 
has_timestamp_absolute_us() const30771   bool has_timestamp_absolute_us() const { return _has_field_[16]; }
timestamp_absolute_us() const30772   int64_t timestamp_absolute_us() const { return timestamp_absolute_us_; }
set_timestamp_absolute_us(int64_t value)30773   void set_timestamp_absolute_us(int64_t value) { timestamp_absolute_us_ = value; _has_field_.set(16); }
30774 
has_thread_time_delta_us() const30775   bool has_thread_time_delta_us() const { return _has_field_[2]; }
thread_time_delta_us() const30776   int64_t thread_time_delta_us() const { return thread_time_delta_us_; }
set_thread_time_delta_us(int64_t value)30777   void set_thread_time_delta_us(int64_t value) { thread_time_delta_us_ = value; _has_field_.set(2); }
30778 
has_thread_time_absolute_us() const30779   bool has_thread_time_absolute_us() const { return _has_field_[17]; }
thread_time_absolute_us() const30780   int64_t thread_time_absolute_us() const { return thread_time_absolute_us_; }
set_thread_time_absolute_us(int64_t value)30781   void set_thread_time_absolute_us(int64_t value) { thread_time_absolute_us_ = value; _has_field_.set(17); }
30782 
has_thread_instruction_count_delta() const30783   bool has_thread_instruction_count_delta() const { return _has_field_[8]; }
thread_instruction_count_delta() const30784   int64_t thread_instruction_count_delta() const { return thread_instruction_count_delta_; }
set_thread_instruction_count_delta(int64_t value)30785   void set_thread_instruction_count_delta(int64_t value) { thread_instruction_count_delta_ = value; _has_field_.set(8); }
30786 
has_thread_instruction_count_absolute() const30787   bool has_thread_instruction_count_absolute() const { return _has_field_[20]; }
thread_instruction_count_absolute() const30788   int64_t thread_instruction_count_absolute() const { return thread_instruction_count_absolute_; }
set_thread_instruction_count_absolute(int64_t value)30789   void set_thread_instruction_count_absolute(int64_t value) { thread_instruction_count_absolute_ = value; _has_field_.set(20); }
30790 
has_legacy_event() const30791   bool has_legacy_event() const { return _has_field_[6]; }
legacy_event() const30792   const TrackEvent_LegacyEvent& legacy_event() const { return *legacy_event_; }
mutable_legacy_event()30793   TrackEvent_LegacyEvent* mutable_legacy_event() { _has_field_.set(6); return legacy_event_.get(); }
30794 
30795  private:
30796   std::vector<uint64_t> category_iids_;
30797   std::vector<std::string> categories_;
30798   uint64_t name_iid_{};
30799   std::string name_{};
30800   TrackEvent_Type type_{};
30801   uint64_t track_uuid_{};
30802   int64_t counter_value_{};
30803   double double_counter_value_{};
30804   std::vector<uint64_t> extra_counter_track_uuids_;
30805   std::vector<int64_t> extra_counter_values_;
30806   std::vector<uint64_t> extra_double_counter_track_uuids_;
30807   std::vector<double> extra_double_counter_values_;
30808   std::vector<uint64_t> flow_ids_;
30809   std::vector<uint64_t> terminating_flow_ids_;
30810   std::vector<DebugAnnotation> debug_annotations_;
30811   ::protozero::CopyablePtr<TaskExecution> task_execution_;
30812   ::protozero::CopyablePtr<LogMessage> log_message_;
30813   ::protozero::CopyablePtr<ChromeCompositorSchedulerState> cc_scheduler_state_;
30814   ::protozero::CopyablePtr<ChromeUserEvent> chrome_user_event_;
30815   ::protozero::CopyablePtr<ChromeKeyedService> chrome_keyed_service_;
30816   ::protozero::CopyablePtr<ChromeLegacyIpc> chrome_legacy_ipc_;
30817   ::protozero::CopyablePtr<ChromeHistogramSample> chrome_histogram_sample_;
30818   ::protozero::CopyablePtr<ChromeLatencyInfo> chrome_latency_info_;
30819   ::protozero::CopyablePtr<ChromeFrameReporter> chrome_frame_reporter_;
30820   ::protozero::CopyablePtr<ChromeApplicationStateInfo> chrome_application_state_info_;
30821   ::protozero::CopyablePtr<ChromeRendererSchedulerState> chrome_renderer_scheduler_state_;
30822   ::protozero::CopyablePtr<ChromeWindowHandleEventInfo> chrome_window_handle_event_info_;
30823   ::protozero::CopyablePtr<ChromeContentSettingsEventInfo> chrome_content_settings_event_info_;
30824   ::protozero::CopyablePtr<SourceLocation> source_location_;
30825   uint64_t source_location_iid_{};
30826   ::protozero::CopyablePtr<ChromeMessagePump> chrome_message_pump_;
30827   ::protozero::CopyablePtr<ChromeMojoEventInfo> chrome_mojo_event_info_;
30828   int64_t timestamp_delta_us_{};
30829   int64_t timestamp_absolute_us_{};
30830   int64_t thread_time_delta_us_{};
30831   int64_t thread_time_absolute_us_{};
30832   int64_t thread_instruction_count_delta_{};
30833   int64_t thread_instruction_count_absolute_{};
30834   ::protozero::CopyablePtr<TrackEvent_LegacyEvent> legacy_event_;
30835 
30836   // Allows to preserve unknown protobuf fields for compatibility
30837   // with future versions of .proto files.
30838   std::string unknown_fields_;
30839 
30840   std::bitset<47> _has_field_{};
30841 };
30842 
30843 
30844 class PERFETTO_EXPORT TrackEvent_LegacyEvent : public ::protozero::CppMessageObj {
30845  public:
30846   using FlowDirection = TrackEvent_LegacyEvent_FlowDirection;
30847   static constexpr auto FLOW_UNSPECIFIED = TrackEvent_LegacyEvent_FlowDirection_FLOW_UNSPECIFIED;
30848   static constexpr auto FLOW_IN = TrackEvent_LegacyEvent_FlowDirection_FLOW_IN;
30849   static constexpr auto FLOW_OUT = TrackEvent_LegacyEvent_FlowDirection_FLOW_OUT;
30850   static constexpr auto FLOW_INOUT = TrackEvent_LegacyEvent_FlowDirection_FLOW_INOUT;
30851   static constexpr auto FlowDirection_MIN = TrackEvent_LegacyEvent_FlowDirection_FLOW_UNSPECIFIED;
30852   static constexpr auto FlowDirection_MAX = TrackEvent_LegacyEvent_FlowDirection_FLOW_INOUT;
30853   using InstantEventScope = TrackEvent_LegacyEvent_InstantEventScope;
30854   static constexpr auto SCOPE_UNSPECIFIED = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_UNSPECIFIED;
30855   static constexpr auto SCOPE_GLOBAL = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_GLOBAL;
30856   static constexpr auto SCOPE_PROCESS = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_PROCESS;
30857   static constexpr auto SCOPE_THREAD = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_THREAD;
30858   static constexpr auto InstantEventScope_MIN = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_UNSPECIFIED;
30859   static constexpr auto InstantEventScope_MAX = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_THREAD;
30860   enum FieldNumbers {
30861     kNameIidFieldNumber = 1,
30862     kPhaseFieldNumber = 2,
30863     kDurationUsFieldNumber = 3,
30864     kThreadDurationUsFieldNumber = 4,
30865     kThreadInstructionDeltaFieldNumber = 15,
30866     kUnscopedIdFieldNumber = 6,
30867     kLocalIdFieldNumber = 10,
30868     kGlobalIdFieldNumber = 11,
30869     kIdScopeFieldNumber = 7,
30870     kUseAsyncTtsFieldNumber = 9,
30871     kBindIdFieldNumber = 8,
30872     kBindToEnclosingFieldNumber = 12,
30873     kFlowDirectionFieldNumber = 13,
30874     kInstantEventScopeFieldNumber = 14,
30875     kPidOverrideFieldNumber = 18,
30876     kTidOverrideFieldNumber = 19,
30877   };
30878 
30879   TrackEvent_LegacyEvent();
30880   ~TrackEvent_LegacyEvent() override;
30881   TrackEvent_LegacyEvent(TrackEvent_LegacyEvent&&) noexcept;
30882   TrackEvent_LegacyEvent& operator=(TrackEvent_LegacyEvent&&);
30883   TrackEvent_LegacyEvent(const TrackEvent_LegacyEvent&);
30884   TrackEvent_LegacyEvent& operator=(const TrackEvent_LegacyEvent&);
30885   bool operator==(const TrackEvent_LegacyEvent&) const;
operator !=(const TrackEvent_LegacyEvent & other) const30886   bool operator!=(const TrackEvent_LegacyEvent& other) const { return !(*this == other); }
30887 
30888   bool ParseFromArray(const void*, size_t) override;
30889   std::string SerializeAsString() const override;
30890   std::vector<uint8_t> SerializeAsArray() const override;
30891   void Serialize(::protozero::Message*) const;
30892 
has_name_iid() const30893   bool has_name_iid() const { return _has_field_[1]; }
name_iid() const30894   uint64_t name_iid() const { return name_iid_; }
set_name_iid(uint64_t value)30895   void set_name_iid(uint64_t value) { name_iid_ = value; _has_field_.set(1); }
30896 
has_phase() const30897   bool has_phase() const { return _has_field_[2]; }
phase() const30898   int32_t phase() const { return phase_; }
set_phase(int32_t value)30899   void set_phase(int32_t value) { phase_ = value; _has_field_.set(2); }
30900 
has_duration_us() const30901   bool has_duration_us() const { return _has_field_[3]; }
duration_us() const30902   int64_t duration_us() const { return duration_us_; }
set_duration_us(int64_t value)30903   void set_duration_us(int64_t value) { duration_us_ = value; _has_field_.set(3); }
30904 
has_thread_duration_us() const30905   bool has_thread_duration_us() const { return _has_field_[4]; }
thread_duration_us() const30906   int64_t thread_duration_us() const { return thread_duration_us_; }
set_thread_duration_us(int64_t value)30907   void set_thread_duration_us(int64_t value) { thread_duration_us_ = value; _has_field_.set(4); }
30908 
has_thread_instruction_delta() const30909   bool has_thread_instruction_delta() const { return _has_field_[15]; }
thread_instruction_delta() const30910   int64_t thread_instruction_delta() const { return thread_instruction_delta_; }
set_thread_instruction_delta(int64_t value)30911   void set_thread_instruction_delta(int64_t value) { thread_instruction_delta_ = value; _has_field_.set(15); }
30912 
has_unscoped_id() const30913   bool has_unscoped_id() const { return _has_field_[6]; }
unscoped_id() const30914   uint64_t unscoped_id() const { return unscoped_id_; }
set_unscoped_id(uint64_t value)30915   void set_unscoped_id(uint64_t value) { unscoped_id_ = value; _has_field_.set(6); }
30916 
has_local_id() const30917   bool has_local_id() const { return _has_field_[10]; }
local_id() const30918   uint64_t local_id() const { return local_id_; }
set_local_id(uint64_t value)30919   void set_local_id(uint64_t value) { local_id_ = value; _has_field_.set(10); }
30920 
has_global_id() const30921   bool has_global_id() const { return _has_field_[11]; }
global_id() const30922   uint64_t global_id() const { return global_id_; }
set_global_id(uint64_t value)30923   void set_global_id(uint64_t value) { global_id_ = value; _has_field_.set(11); }
30924 
has_id_scope() const30925   bool has_id_scope() const { return _has_field_[7]; }
id_scope() const30926   const std::string& id_scope() const { return id_scope_; }
set_id_scope(const std::string & value)30927   void set_id_scope(const std::string& value) { id_scope_ = value; _has_field_.set(7); }
30928 
has_use_async_tts() const30929   bool has_use_async_tts() const { return _has_field_[9]; }
use_async_tts() const30930   bool use_async_tts() const { return use_async_tts_; }
set_use_async_tts(bool value)30931   void set_use_async_tts(bool value) { use_async_tts_ = value; _has_field_.set(9); }
30932 
has_bind_id() const30933   bool has_bind_id() const { return _has_field_[8]; }
bind_id() const30934   uint64_t bind_id() const { return bind_id_; }
set_bind_id(uint64_t value)30935   void set_bind_id(uint64_t value) { bind_id_ = value; _has_field_.set(8); }
30936 
has_bind_to_enclosing() const30937   bool has_bind_to_enclosing() const { return _has_field_[12]; }
bind_to_enclosing() const30938   bool bind_to_enclosing() const { return bind_to_enclosing_; }
set_bind_to_enclosing(bool value)30939   void set_bind_to_enclosing(bool value) { bind_to_enclosing_ = value; _has_field_.set(12); }
30940 
has_flow_direction() const30941   bool has_flow_direction() const { return _has_field_[13]; }
flow_direction() const30942   TrackEvent_LegacyEvent_FlowDirection flow_direction() const { return flow_direction_; }
set_flow_direction(TrackEvent_LegacyEvent_FlowDirection value)30943   void set_flow_direction(TrackEvent_LegacyEvent_FlowDirection value) { flow_direction_ = value; _has_field_.set(13); }
30944 
has_instant_event_scope() const30945   bool has_instant_event_scope() const { return _has_field_[14]; }
instant_event_scope() const30946   TrackEvent_LegacyEvent_InstantEventScope instant_event_scope() const { return instant_event_scope_; }
set_instant_event_scope(TrackEvent_LegacyEvent_InstantEventScope value)30947   void set_instant_event_scope(TrackEvent_LegacyEvent_InstantEventScope value) { instant_event_scope_ = value; _has_field_.set(14); }
30948 
has_pid_override() const30949   bool has_pid_override() const { return _has_field_[18]; }
pid_override() const30950   int32_t pid_override() const { return pid_override_; }
set_pid_override(int32_t value)30951   void set_pid_override(int32_t value) { pid_override_ = value; _has_field_.set(18); }
30952 
has_tid_override() const30953   bool has_tid_override() const { return _has_field_[19]; }
tid_override() const30954   int32_t tid_override() const { return tid_override_; }
set_tid_override(int32_t value)30955   void set_tid_override(int32_t value) { tid_override_ = value; _has_field_.set(19); }
30956 
30957  private:
30958   uint64_t name_iid_{};
30959   int32_t phase_{};
30960   int64_t duration_us_{};
30961   int64_t thread_duration_us_{};
30962   int64_t thread_instruction_delta_{};
30963   uint64_t unscoped_id_{};
30964   uint64_t local_id_{};
30965   uint64_t global_id_{};
30966   std::string id_scope_{};
30967   bool use_async_tts_{};
30968   uint64_t bind_id_{};
30969   bool bind_to_enclosing_{};
30970   TrackEvent_LegacyEvent_FlowDirection flow_direction_{};
30971   TrackEvent_LegacyEvent_InstantEventScope instant_event_scope_{};
30972   int32_t pid_override_{};
30973   int32_t tid_override_{};
30974 
30975   // Allows to preserve unknown protobuf fields for compatibility
30976   // with future versions of .proto files.
30977   std::string unknown_fields_;
30978 
30979   std::bitset<20> _has_field_{};
30980 };
30981 
30982 }  // namespace perfetto
30983 }  // namespace protos
30984 }  // namespace gen
30985 
30986 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TRACK_EVENT_PROTO_CPP_H_
30987 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
30988 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
30989 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
30990 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
30991 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
30992 #if defined(__GNUC__) || defined(__clang__)
30993 #pragma GCC diagnostic push
30994 #pragma GCC diagnostic ignored "-Wfloat-equal"
30995 #endif
30996 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.gen.h"
30997 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/source_location.gen.h"
30998 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_window_handle_event_info.gen.h"
30999 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_user_event.gen.h"
31000 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.gen.h"
31001 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_mojo_event_info.gen.h"
31002 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_message_pump.gen.h"
31003 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_legacy_ipc.gen.h"
31004 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_latency_info.gen.h"
31005 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_keyed_service.gen.h"
31006 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_histogram_sample.gen.h"
31007 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_frame_reporter.gen.h"
31008 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_content_settings_event_info.gen.h"
31009 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.gen.h"
31010 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_application_state_info.gen.h"
31011 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/task_execution.gen.h"
31012 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/log_message.gen.h"
31013 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.gen.h"
31014 
31015 namespace perfetto {
31016 namespace protos {
31017 namespace gen {
31018 
31019 EventName::EventName() = default;
31020 EventName::~EventName() = default;
31021 EventName::EventName(const EventName&) = default;
31022 EventName& EventName::operator=(const EventName&) = default;
31023 EventName::EventName(EventName&&) noexcept = default;
31024 EventName& EventName::operator=(EventName&&) = default;
31025 
operator ==(const EventName & other) const31026 bool EventName::operator==(const EventName& other) const {
31027   return unknown_fields_ == other.unknown_fields_
31028    && iid_ == other.iid_
31029    && name_ == other.name_;
31030 }
31031 
ParseFromArray(const void * raw,size_t size)31032 bool EventName::ParseFromArray(const void* raw, size_t size) {
31033   unknown_fields_.clear();
31034   bool packed_error = false;
31035 
31036   ::protozero::ProtoDecoder dec(raw, size);
31037   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
31038     if (field.id() < _has_field_.size()) {
31039       _has_field_.set(field.id());
31040     }
31041     switch (field.id()) {
31042       case 1 /* iid */:
31043         field.get(&iid_);
31044         break;
31045       case 2 /* name */:
31046         field.get(&name_);
31047         break;
31048       default:
31049         field.SerializeAndAppendTo(&unknown_fields_);
31050         break;
31051     }
31052   }
31053   return !packed_error && !dec.bytes_left();
31054 }
31055 
SerializeAsString() const31056 std::string EventName::SerializeAsString() const {
31057   ::protozero::HeapBuffered<::protozero::Message> msg;
31058   Serialize(msg.get());
31059   return msg.SerializeAsString();
31060 }
31061 
SerializeAsArray() const31062 std::vector<uint8_t> EventName::SerializeAsArray() const {
31063   ::protozero::HeapBuffered<::protozero::Message> msg;
31064   Serialize(msg.get());
31065   return msg.SerializeAsArray();
31066 }
31067 
Serialize(::protozero::Message * msg) const31068 void EventName::Serialize(::protozero::Message* msg) const {
31069   // Field 1: iid
31070   if (_has_field_[1]) {
31071     msg->AppendVarInt(1, iid_);
31072   }
31073 
31074   // Field 2: name
31075   if (_has_field_[2]) {
31076     msg->AppendString(2, name_);
31077   }
31078 
31079   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
31080 }
31081 
31082 
31083 EventCategory::EventCategory() = default;
31084 EventCategory::~EventCategory() = default;
31085 EventCategory::EventCategory(const EventCategory&) = default;
31086 EventCategory& EventCategory::operator=(const EventCategory&) = default;
31087 EventCategory::EventCategory(EventCategory&&) noexcept = default;
31088 EventCategory& EventCategory::operator=(EventCategory&&) = default;
31089 
operator ==(const EventCategory & other) const31090 bool EventCategory::operator==(const EventCategory& other) const {
31091   return unknown_fields_ == other.unknown_fields_
31092    && iid_ == other.iid_
31093    && name_ == other.name_;
31094 }
31095 
ParseFromArray(const void * raw,size_t size)31096 bool EventCategory::ParseFromArray(const void* raw, size_t size) {
31097   unknown_fields_.clear();
31098   bool packed_error = false;
31099 
31100   ::protozero::ProtoDecoder dec(raw, size);
31101   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
31102     if (field.id() < _has_field_.size()) {
31103       _has_field_.set(field.id());
31104     }
31105     switch (field.id()) {
31106       case 1 /* iid */:
31107         field.get(&iid_);
31108         break;
31109       case 2 /* name */:
31110         field.get(&name_);
31111         break;
31112       default:
31113         field.SerializeAndAppendTo(&unknown_fields_);
31114         break;
31115     }
31116   }
31117   return !packed_error && !dec.bytes_left();
31118 }
31119 
SerializeAsString() const31120 std::string EventCategory::SerializeAsString() const {
31121   ::protozero::HeapBuffered<::protozero::Message> msg;
31122   Serialize(msg.get());
31123   return msg.SerializeAsString();
31124 }
31125 
SerializeAsArray() const31126 std::vector<uint8_t> EventCategory::SerializeAsArray() const {
31127   ::protozero::HeapBuffered<::protozero::Message> msg;
31128   Serialize(msg.get());
31129   return msg.SerializeAsArray();
31130 }
31131 
Serialize(::protozero::Message * msg) const31132 void EventCategory::Serialize(::protozero::Message* msg) const {
31133   // Field 1: iid
31134   if (_has_field_[1]) {
31135     msg->AppendVarInt(1, iid_);
31136   }
31137 
31138   // Field 2: name
31139   if (_has_field_[2]) {
31140     msg->AppendString(2, name_);
31141   }
31142 
31143   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
31144 }
31145 
31146 
31147 TrackEventDefaults::TrackEventDefaults() = default;
31148 TrackEventDefaults::~TrackEventDefaults() = default;
31149 TrackEventDefaults::TrackEventDefaults(const TrackEventDefaults&) = default;
31150 TrackEventDefaults& TrackEventDefaults::operator=(const TrackEventDefaults&) = default;
31151 TrackEventDefaults::TrackEventDefaults(TrackEventDefaults&&) noexcept = default;
31152 TrackEventDefaults& TrackEventDefaults::operator=(TrackEventDefaults&&) = default;
31153 
operator ==(const TrackEventDefaults & other) const31154 bool TrackEventDefaults::operator==(const TrackEventDefaults& other) const {
31155   return unknown_fields_ == other.unknown_fields_
31156    && track_uuid_ == other.track_uuid_
31157    && extra_counter_track_uuids_ == other.extra_counter_track_uuids_
31158    && extra_double_counter_track_uuids_ == other.extra_double_counter_track_uuids_;
31159 }
31160 
ParseFromArray(const void * raw,size_t size)31161 bool TrackEventDefaults::ParseFromArray(const void* raw, size_t size) {
31162   extra_counter_track_uuids_.clear();
31163   extra_double_counter_track_uuids_.clear();
31164   unknown_fields_.clear();
31165   bool packed_error = false;
31166 
31167   ::protozero::ProtoDecoder dec(raw, size);
31168   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
31169     if (field.id() < _has_field_.size()) {
31170       _has_field_.set(field.id());
31171     }
31172     switch (field.id()) {
31173       case 11 /* track_uuid */:
31174         field.get(&track_uuid_);
31175         break;
31176       case 31 /* extra_counter_track_uuids */:
31177         extra_counter_track_uuids_.emplace_back();
31178         field.get(&extra_counter_track_uuids_.back());
31179         break;
31180       case 45 /* extra_double_counter_track_uuids */:
31181         extra_double_counter_track_uuids_.emplace_back();
31182         field.get(&extra_double_counter_track_uuids_.back());
31183         break;
31184       default:
31185         field.SerializeAndAppendTo(&unknown_fields_);
31186         break;
31187     }
31188   }
31189   return !packed_error && !dec.bytes_left();
31190 }
31191 
SerializeAsString() const31192 std::string TrackEventDefaults::SerializeAsString() const {
31193   ::protozero::HeapBuffered<::protozero::Message> msg;
31194   Serialize(msg.get());
31195   return msg.SerializeAsString();
31196 }
31197 
SerializeAsArray() const31198 std::vector<uint8_t> TrackEventDefaults::SerializeAsArray() const {
31199   ::protozero::HeapBuffered<::protozero::Message> msg;
31200   Serialize(msg.get());
31201   return msg.SerializeAsArray();
31202 }
31203 
Serialize(::protozero::Message * msg) const31204 void TrackEventDefaults::Serialize(::protozero::Message* msg) const {
31205   // Field 11: track_uuid
31206   if (_has_field_[11]) {
31207     msg->AppendVarInt(11, track_uuid_);
31208   }
31209 
31210   // Field 31: extra_counter_track_uuids
31211   for (auto& it : extra_counter_track_uuids_) {
31212     msg->AppendVarInt(31, it);
31213   }
31214 
31215   // Field 45: extra_double_counter_track_uuids
31216   for (auto& it : extra_double_counter_track_uuids_) {
31217     msg->AppendVarInt(45, it);
31218   }
31219 
31220   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
31221 }
31222 
31223 
31224 TrackEvent::TrackEvent() = default;
31225 TrackEvent::~TrackEvent() = default;
31226 TrackEvent::TrackEvent(const TrackEvent&) = default;
31227 TrackEvent& TrackEvent::operator=(const TrackEvent&) = default;
31228 TrackEvent::TrackEvent(TrackEvent&&) noexcept = default;
31229 TrackEvent& TrackEvent::operator=(TrackEvent&&) = default;
31230 
operator ==(const TrackEvent & other) const31231 bool TrackEvent::operator==(const TrackEvent& other) const {
31232   return unknown_fields_ == other.unknown_fields_
31233    && category_iids_ == other.category_iids_
31234    && categories_ == other.categories_
31235    && name_iid_ == other.name_iid_
31236    && name_ == other.name_
31237    && type_ == other.type_
31238    && track_uuid_ == other.track_uuid_
31239    && counter_value_ == other.counter_value_
31240    && double_counter_value_ == other.double_counter_value_
31241    && extra_counter_track_uuids_ == other.extra_counter_track_uuids_
31242    && extra_counter_values_ == other.extra_counter_values_
31243    && extra_double_counter_track_uuids_ == other.extra_double_counter_track_uuids_
31244    && extra_double_counter_values_ == other.extra_double_counter_values_
31245    && flow_ids_ == other.flow_ids_
31246    && terminating_flow_ids_ == other.terminating_flow_ids_
31247    && debug_annotations_ == other.debug_annotations_
31248    && task_execution_ == other.task_execution_
31249    && log_message_ == other.log_message_
31250    && cc_scheduler_state_ == other.cc_scheduler_state_
31251    && chrome_user_event_ == other.chrome_user_event_
31252    && chrome_keyed_service_ == other.chrome_keyed_service_
31253    && chrome_legacy_ipc_ == other.chrome_legacy_ipc_
31254    && chrome_histogram_sample_ == other.chrome_histogram_sample_
31255    && chrome_latency_info_ == other.chrome_latency_info_
31256    && chrome_frame_reporter_ == other.chrome_frame_reporter_
31257    && chrome_application_state_info_ == other.chrome_application_state_info_
31258    && chrome_renderer_scheduler_state_ == other.chrome_renderer_scheduler_state_
31259    && chrome_window_handle_event_info_ == other.chrome_window_handle_event_info_
31260    && chrome_content_settings_event_info_ == other.chrome_content_settings_event_info_
31261    && source_location_ == other.source_location_
31262    && source_location_iid_ == other.source_location_iid_
31263    && chrome_message_pump_ == other.chrome_message_pump_
31264    && chrome_mojo_event_info_ == other.chrome_mojo_event_info_
31265    && timestamp_delta_us_ == other.timestamp_delta_us_
31266    && timestamp_absolute_us_ == other.timestamp_absolute_us_
31267    && thread_time_delta_us_ == other.thread_time_delta_us_
31268    && thread_time_absolute_us_ == other.thread_time_absolute_us_
31269    && thread_instruction_count_delta_ == other.thread_instruction_count_delta_
31270    && thread_instruction_count_absolute_ == other.thread_instruction_count_absolute_
31271    && legacy_event_ == other.legacy_event_;
31272 }
31273 
debug_annotations_size() const31274 int TrackEvent::debug_annotations_size() const { return static_cast<int>(debug_annotations_.size()); }
clear_debug_annotations()31275 void TrackEvent::clear_debug_annotations() { debug_annotations_.clear(); }
add_debug_annotations()31276 DebugAnnotation* TrackEvent::add_debug_annotations() { debug_annotations_.emplace_back(); return &debug_annotations_.back(); }
ParseFromArray(const void * raw,size_t size)31277 bool TrackEvent::ParseFromArray(const void* raw, size_t size) {
31278   category_iids_.clear();
31279   categories_.clear();
31280   extra_counter_track_uuids_.clear();
31281   extra_counter_values_.clear();
31282   extra_double_counter_track_uuids_.clear();
31283   extra_double_counter_values_.clear();
31284   flow_ids_.clear();
31285   terminating_flow_ids_.clear();
31286   debug_annotations_.clear();
31287   unknown_fields_.clear();
31288   bool packed_error = false;
31289 
31290   ::protozero::ProtoDecoder dec(raw, size);
31291   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
31292     if (field.id() < _has_field_.size()) {
31293       _has_field_.set(field.id());
31294     }
31295     switch (field.id()) {
31296       case 3 /* category_iids */:
31297         category_iids_.emplace_back();
31298         field.get(&category_iids_.back());
31299         break;
31300       case 22 /* categories */:
31301         categories_.emplace_back();
31302         field.get(&categories_.back());
31303         break;
31304       case 10 /* name_iid */:
31305         field.get(&name_iid_);
31306         break;
31307       case 23 /* name */:
31308         field.get(&name_);
31309         break;
31310       case 9 /* type */:
31311         field.get(&type_);
31312         break;
31313       case 11 /* track_uuid */:
31314         field.get(&track_uuid_);
31315         break;
31316       case 30 /* counter_value */:
31317         field.get(&counter_value_);
31318         break;
31319       case 44 /* double_counter_value */:
31320         field.get(&double_counter_value_);
31321         break;
31322       case 31 /* extra_counter_track_uuids */:
31323         extra_counter_track_uuids_.emplace_back();
31324         field.get(&extra_counter_track_uuids_.back());
31325         break;
31326       case 12 /* extra_counter_values */:
31327         extra_counter_values_.emplace_back();
31328         field.get(&extra_counter_values_.back());
31329         break;
31330       case 45 /* extra_double_counter_track_uuids */:
31331         extra_double_counter_track_uuids_.emplace_back();
31332         field.get(&extra_double_counter_track_uuids_.back());
31333         break;
31334       case 46 /* extra_double_counter_values */:
31335         extra_double_counter_values_.emplace_back();
31336         field.get(&extra_double_counter_values_.back());
31337         break;
31338       case 36 /* flow_ids */:
31339         flow_ids_.emplace_back();
31340         field.get(&flow_ids_.back());
31341         break;
31342       case 42 /* terminating_flow_ids */:
31343         terminating_flow_ids_.emplace_back();
31344         field.get(&terminating_flow_ids_.back());
31345         break;
31346       case 4 /* debug_annotations */:
31347         debug_annotations_.emplace_back();
31348         debug_annotations_.back().ParseFromArray(field.data(), field.size());
31349         break;
31350       case 5 /* task_execution */:
31351         (*task_execution_).ParseFromArray(field.data(), field.size());
31352         break;
31353       case 21 /* log_message */:
31354         (*log_message_).ParseFromArray(field.data(), field.size());
31355         break;
31356       case 24 /* cc_scheduler_state */:
31357         (*cc_scheduler_state_).ParseFromArray(field.data(), field.size());
31358         break;
31359       case 25 /* chrome_user_event */:
31360         (*chrome_user_event_).ParseFromArray(field.data(), field.size());
31361         break;
31362       case 26 /* chrome_keyed_service */:
31363         (*chrome_keyed_service_).ParseFromArray(field.data(), field.size());
31364         break;
31365       case 27 /* chrome_legacy_ipc */:
31366         (*chrome_legacy_ipc_).ParseFromArray(field.data(), field.size());
31367         break;
31368       case 28 /* chrome_histogram_sample */:
31369         (*chrome_histogram_sample_).ParseFromArray(field.data(), field.size());
31370         break;
31371       case 29 /* chrome_latency_info */:
31372         (*chrome_latency_info_).ParseFromArray(field.data(), field.size());
31373         break;
31374       case 32 /* chrome_frame_reporter */:
31375         (*chrome_frame_reporter_).ParseFromArray(field.data(), field.size());
31376         break;
31377       case 39 /* chrome_application_state_info */:
31378         (*chrome_application_state_info_).ParseFromArray(field.data(), field.size());
31379         break;
31380       case 40 /* chrome_renderer_scheduler_state */:
31381         (*chrome_renderer_scheduler_state_).ParseFromArray(field.data(), field.size());
31382         break;
31383       case 41 /* chrome_window_handle_event_info */:
31384         (*chrome_window_handle_event_info_).ParseFromArray(field.data(), field.size());
31385         break;
31386       case 43 /* chrome_content_settings_event_info */:
31387         (*chrome_content_settings_event_info_).ParseFromArray(field.data(), field.size());
31388         break;
31389       case 33 /* source_location */:
31390         (*source_location_).ParseFromArray(field.data(), field.size());
31391         break;
31392       case 34 /* source_location_iid */:
31393         field.get(&source_location_iid_);
31394         break;
31395       case 35 /* chrome_message_pump */:
31396         (*chrome_message_pump_).ParseFromArray(field.data(), field.size());
31397         break;
31398       case 38 /* chrome_mojo_event_info */:
31399         (*chrome_mojo_event_info_).ParseFromArray(field.data(), field.size());
31400         break;
31401       case 1 /* timestamp_delta_us */:
31402         field.get(&timestamp_delta_us_);
31403         break;
31404       case 16 /* timestamp_absolute_us */:
31405         field.get(&timestamp_absolute_us_);
31406         break;
31407       case 2 /* thread_time_delta_us */:
31408         field.get(&thread_time_delta_us_);
31409         break;
31410       case 17 /* thread_time_absolute_us */:
31411         field.get(&thread_time_absolute_us_);
31412         break;
31413       case 8 /* thread_instruction_count_delta */:
31414         field.get(&thread_instruction_count_delta_);
31415         break;
31416       case 20 /* thread_instruction_count_absolute */:
31417         field.get(&thread_instruction_count_absolute_);
31418         break;
31419       case 6 /* legacy_event */:
31420         (*legacy_event_).ParseFromArray(field.data(), field.size());
31421         break;
31422       default:
31423         field.SerializeAndAppendTo(&unknown_fields_);
31424         break;
31425     }
31426   }
31427   return !packed_error && !dec.bytes_left();
31428 }
31429 
SerializeAsString() const31430 std::string TrackEvent::SerializeAsString() const {
31431   ::protozero::HeapBuffered<::protozero::Message> msg;
31432   Serialize(msg.get());
31433   return msg.SerializeAsString();
31434 }
31435 
SerializeAsArray() const31436 std::vector<uint8_t> TrackEvent::SerializeAsArray() const {
31437   ::protozero::HeapBuffered<::protozero::Message> msg;
31438   Serialize(msg.get());
31439   return msg.SerializeAsArray();
31440 }
31441 
Serialize(::protozero::Message * msg) const31442 void TrackEvent::Serialize(::protozero::Message* msg) const {
31443   // Field 3: category_iids
31444   for (auto& it : category_iids_) {
31445     msg->AppendVarInt(3, it);
31446   }
31447 
31448   // Field 22: categories
31449   for (auto& it : categories_) {
31450     msg->AppendString(22, it);
31451   }
31452 
31453   // Field 10: name_iid
31454   if (_has_field_[10]) {
31455     msg->AppendVarInt(10, name_iid_);
31456   }
31457 
31458   // Field 23: name
31459   if (_has_field_[23]) {
31460     msg->AppendString(23, name_);
31461   }
31462 
31463   // Field 9: type
31464   if (_has_field_[9]) {
31465     msg->AppendVarInt(9, type_);
31466   }
31467 
31468   // Field 11: track_uuid
31469   if (_has_field_[11]) {
31470     msg->AppendVarInt(11, track_uuid_);
31471   }
31472 
31473   // Field 30: counter_value
31474   if (_has_field_[30]) {
31475     msg->AppendVarInt(30, counter_value_);
31476   }
31477 
31478   // Field 44: double_counter_value
31479   if (_has_field_[44]) {
31480     msg->AppendFixed(44, double_counter_value_);
31481   }
31482 
31483   // Field 31: extra_counter_track_uuids
31484   for (auto& it : extra_counter_track_uuids_) {
31485     msg->AppendVarInt(31, it);
31486   }
31487 
31488   // Field 12: extra_counter_values
31489   for (auto& it : extra_counter_values_) {
31490     msg->AppendVarInt(12, it);
31491   }
31492 
31493   // Field 45: extra_double_counter_track_uuids
31494   for (auto& it : extra_double_counter_track_uuids_) {
31495     msg->AppendVarInt(45, it);
31496   }
31497 
31498   // Field 46: extra_double_counter_values
31499   for (auto& it : extra_double_counter_values_) {
31500     msg->AppendFixed(46, it);
31501   }
31502 
31503   // Field 36: flow_ids
31504   for (auto& it : flow_ids_) {
31505     msg->AppendVarInt(36, it);
31506   }
31507 
31508   // Field 42: terminating_flow_ids
31509   for (auto& it : terminating_flow_ids_) {
31510     msg->AppendVarInt(42, it);
31511   }
31512 
31513   // Field 4: debug_annotations
31514   for (auto& it : debug_annotations_) {
31515     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
31516   }
31517 
31518   // Field 5: task_execution
31519   if (_has_field_[5]) {
31520     (*task_execution_).Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
31521   }
31522 
31523   // Field 21: log_message
31524   if (_has_field_[21]) {
31525     (*log_message_).Serialize(msg->BeginNestedMessage<::protozero::Message>(21));
31526   }
31527 
31528   // Field 24: cc_scheduler_state
31529   if (_has_field_[24]) {
31530     (*cc_scheduler_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(24));
31531   }
31532 
31533   // Field 25: chrome_user_event
31534   if (_has_field_[25]) {
31535     (*chrome_user_event_).Serialize(msg->BeginNestedMessage<::protozero::Message>(25));
31536   }
31537 
31538   // Field 26: chrome_keyed_service
31539   if (_has_field_[26]) {
31540     (*chrome_keyed_service_).Serialize(msg->BeginNestedMessage<::protozero::Message>(26));
31541   }
31542 
31543   // Field 27: chrome_legacy_ipc
31544   if (_has_field_[27]) {
31545     (*chrome_legacy_ipc_).Serialize(msg->BeginNestedMessage<::protozero::Message>(27));
31546   }
31547 
31548   // Field 28: chrome_histogram_sample
31549   if (_has_field_[28]) {
31550     (*chrome_histogram_sample_).Serialize(msg->BeginNestedMessage<::protozero::Message>(28));
31551   }
31552 
31553   // Field 29: chrome_latency_info
31554   if (_has_field_[29]) {
31555     (*chrome_latency_info_).Serialize(msg->BeginNestedMessage<::protozero::Message>(29));
31556   }
31557 
31558   // Field 32: chrome_frame_reporter
31559   if (_has_field_[32]) {
31560     (*chrome_frame_reporter_).Serialize(msg->BeginNestedMessage<::protozero::Message>(32));
31561   }
31562 
31563   // Field 39: chrome_application_state_info
31564   if (_has_field_[39]) {
31565     (*chrome_application_state_info_).Serialize(msg->BeginNestedMessage<::protozero::Message>(39));
31566   }
31567 
31568   // Field 40: chrome_renderer_scheduler_state
31569   if (_has_field_[40]) {
31570     (*chrome_renderer_scheduler_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(40));
31571   }
31572 
31573   // Field 41: chrome_window_handle_event_info
31574   if (_has_field_[41]) {
31575     (*chrome_window_handle_event_info_).Serialize(msg->BeginNestedMessage<::protozero::Message>(41));
31576   }
31577 
31578   // Field 43: chrome_content_settings_event_info
31579   if (_has_field_[43]) {
31580     (*chrome_content_settings_event_info_).Serialize(msg->BeginNestedMessage<::protozero::Message>(43));
31581   }
31582 
31583   // Field 33: source_location
31584   if (_has_field_[33]) {
31585     (*source_location_).Serialize(msg->BeginNestedMessage<::protozero::Message>(33));
31586   }
31587 
31588   // Field 34: source_location_iid
31589   if (_has_field_[34]) {
31590     msg->AppendVarInt(34, source_location_iid_);
31591   }
31592 
31593   // Field 35: chrome_message_pump
31594   if (_has_field_[35]) {
31595     (*chrome_message_pump_).Serialize(msg->BeginNestedMessage<::protozero::Message>(35));
31596   }
31597 
31598   // Field 38: chrome_mojo_event_info
31599   if (_has_field_[38]) {
31600     (*chrome_mojo_event_info_).Serialize(msg->BeginNestedMessage<::protozero::Message>(38));
31601   }
31602 
31603   // Field 1: timestamp_delta_us
31604   if (_has_field_[1]) {
31605     msg->AppendVarInt(1, timestamp_delta_us_);
31606   }
31607 
31608   // Field 16: timestamp_absolute_us
31609   if (_has_field_[16]) {
31610     msg->AppendVarInt(16, timestamp_absolute_us_);
31611   }
31612 
31613   // Field 2: thread_time_delta_us
31614   if (_has_field_[2]) {
31615     msg->AppendVarInt(2, thread_time_delta_us_);
31616   }
31617 
31618   // Field 17: thread_time_absolute_us
31619   if (_has_field_[17]) {
31620     msg->AppendVarInt(17, thread_time_absolute_us_);
31621   }
31622 
31623   // Field 8: thread_instruction_count_delta
31624   if (_has_field_[8]) {
31625     msg->AppendVarInt(8, thread_instruction_count_delta_);
31626   }
31627 
31628   // Field 20: thread_instruction_count_absolute
31629   if (_has_field_[20]) {
31630     msg->AppendVarInt(20, thread_instruction_count_absolute_);
31631   }
31632 
31633   // Field 6: legacy_event
31634   if (_has_field_[6]) {
31635     (*legacy_event_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
31636   }
31637 
31638   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
31639 }
31640 
31641 
31642 TrackEvent_LegacyEvent::TrackEvent_LegacyEvent() = default;
31643 TrackEvent_LegacyEvent::~TrackEvent_LegacyEvent() = default;
31644 TrackEvent_LegacyEvent::TrackEvent_LegacyEvent(const TrackEvent_LegacyEvent&) = default;
31645 TrackEvent_LegacyEvent& TrackEvent_LegacyEvent::operator=(const TrackEvent_LegacyEvent&) = default;
31646 TrackEvent_LegacyEvent::TrackEvent_LegacyEvent(TrackEvent_LegacyEvent&&) noexcept = default;
31647 TrackEvent_LegacyEvent& TrackEvent_LegacyEvent::operator=(TrackEvent_LegacyEvent&&) = default;
31648 
operator ==(const TrackEvent_LegacyEvent & other) const31649 bool TrackEvent_LegacyEvent::operator==(const TrackEvent_LegacyEvent& other) const {
31650   return unknown_fields_ == other.unknown_fields_
31651    && name_iid_ == other.name_iid_
31652    && phase_ == other.phase_
31653    && duration_us_ == other.duration_us_
31654    && thread_duration_us_ == other.thread_duration_us_
31655    && thread_instruction_delta_ == other.thread_instruction_delta_
31656    && unscoped_id_ == other.unscoped_id_
31657    && local_id_ == other.local_id_
31658    && global_id_ == other.global_id_
31659    && id_scope_ == other.id_scope_
31660    && use_async_tts_ == other.use_async_tts_
31661    && bind_id_ == other.bind_id_
31662    && bind_to_enclosing_ == other.bind_to_enclosing_
31663    && flow_direction_ == other.flow_direction_
31664    && instant_event_scope_ == other.instant_event_scope_
31665    && pid_override_ == other.pid_override_
31666    && tid_override_ == other.tid_override_;
31667 }
31668 
ParseFromArray(const void * raw,size_t size)31669 bool TrackEvent_LegacyEvent::ParseFromArray(const void* raw, size_t size) {
31670   unknown_fields_.clear();
31671   bool packed_error = false;
31672 
31673   ::protozero::ProtoDecoder dec(raw, size);
31674   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
31675     if (field.id() < _has_field_.size()) {
31676       _has_field_.set(field.id());
31677     }
31678     switch (field.id()) {
31679       case 1 /* name_iid */:
31680         field.get(&name_iid_);
31681         break;
31682       case 2 /* phase */:
31683         field.get(&phase_);
31684         break;
31685       case 3 /* duration_us */:
31686         field.get(&duration_us_);
31687         break;
31688       case 4 /* thread_duration_us */:
31689         field.get(&thread_duration_us_);
31690         break;
31691       case 15 /* thread_instruction_delta */:
31692         field.get(&thread_instruction_delta_);
31693         break;
31694       case 6 /* unscoped_id */:
31695         field.get(&unscoped_id_);
31696         break;
31697       case 10 /* local_id */:
31698         field.get(&local_id_);
31699         break;
31700       case 11 /* global_id */:
31701         field.get(&global_id_);
31702         break;
31703       case 7 /* id_scope */:
31704         field.get(&id_scope_);
31705         break;
31706       case 9 /* use_async_tts */:
31707         field.get(&use_async_tts_);
31708         break;
31709       case 8 /* bind_id */:
31710         field.get(&bind_id_);
31711         break;
31712       case 12 /* bind_to_enclosing */:
31713         field.get(&bind_to_enclosing_);
31714         break;
31715       case 13 /* flow_direction */:
31716         field.get(&flow_direction_);
31717         break;
31718       case 14 /* instant_event_scope */:
31719         field.get(&instant_event_scope_);
31720         break;
31721       case 18 /* pid_override */:
31722         field.get(&pid_override_);
31723         break;
31724       case 19 /* tid_override */:
31725         field.get(&tid_override_);
31726         break;
31727       default:
31728         field.SerializeAndAppendTo(&unknown_fields_);
31729         break;
31730     }
31731   }
31732   return !packed_error && !dec.bytes_left();
31733 }
31734 
SerializeAsString() const31735 std::string TrackEvent_LegacyEvent::SerializeAsString() const {
31736   ::protozero::HeapBuffered<::protozero::Message> msg;
31737   Serialize(msg.get());
31738   return msg.SerializeAsString();
31739 }
31740 
SerializeAsArray() const31741 std::vector<uint8_t> TrackEvent_LegacyEvent::SerializeAsArray() const {
31742   ::protozero::HeapBuffered<::protozero::Message> msg;
31743   Serialize(msg.get());
31744   return msg.SerializeAsArray();
31745 }
31746 
Serialize(::protozero::Message * msg) const31747 void TrackEvent_LegacyEvent::Serialize(::protozero::Message* msg) const {
31748   // Field 1: name_iid
31749   if (_has_field_[1]) {
31750     msg->AppendVarInt(1, name_iid_);
31751   }
31752 
31753   // Field 2: phase
31754   if (_has_field_[2]) {
31755     msg->AppendVarInt(2, phase_);
31756   }
31757 
31758   // Field 3: duration_us
31759   if (_has_field_[3]) {
31760     msg->AppendVarInt(3, duration_us_);
31761   }
31762 
31763   // Field 4: thread_duration_us
31764   if (_has_field_[4]) {
31765     msg->AppendVarInt(4, thread_duration_us_);
31766   }
31767 
31768   // Field 15: thread_instruction_delta
31769   if (_has_field_[15]) {
31770     msg->AppendVarInt(15, thread_instruction_delta_);
31771   }
31772 
31773   // Field 6: unscoped_id
31774   if (_has_field_[6]) {
31775     msg->AppendVarInt(6, unscoped_id_);
31776   }
31777 
31778   // Field 10: local_id
31779   if (_has_field_[10]) {
31780     msg->AppendVarInt(10, local_id_);
31781   }
31782 
31783   // Field 11: global_id
31784   if (_has_field_[11]) {
31785     msg->AppendVarInt(11, global_id_);
31786   }
31787 
31788   // Field 7: id_scope
31789   if (_has_field_[7]) {
31790     msg->AppendString(7, id_scope_);
31791   }
31792 
31793   // Field 9: use_async_tts
31794   if (_has_field_[9]) {
31795     msg->AppendTinyVarInt(9, use_async_tts_);
31796   }
31797 
31798   // Field 8: bind_id
31799   if (_has_field_[8]) {
31800     msg->AppendVarInt(8, bind_id_);
31801   }
31802 
31803   // Field 12: bind_to_enclosing
31804   if (_has_field_[12]) {
31805     msg->AppendTinyVarInt(12, bind_to_enclosing_);
31806   }
31807 
31808   // Field 13: flow_direction
31809   if (_has_field_[13]) {
31810     msg->AppendVarInt(13, flow_direction_);
31811   }
31812 
31813   // Field 14: instant_event_scope
31814   if (_has_field_[14]) {
31815     msg->AppendVarInt(14, instant_event_scope_);
31816   }
31817 
31818   // Field 18: pid_override
31819   if (_has_field_[18]) {
31820     msg->AppendVarInt(18, pid_override_);
31821   }
31822 
31823   // Field 19: tid_override
31824   if (_has_field_[19]) {
31825     msg->AppendVarInt(19, tid_override_);
31826   }
31827 
31828   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
31829 }
31830 
31831 }  // namespace perfetto
31832 }  // namespace protos
31833 }  // namespace gen
31834 #if defined(__GNUC__) || defined(__clang__)
31835 #pragma GCC diagnostic pop
31836 #endif
31837 // gen_amalgamated begin source: gen/protos/perfetto/config/android/android_log_config.pbzero.cc
31838 // Intentionally empty (crbug.com/998165)
31839 // gen_amalgamated begin source: gen/protos/perfetto/config/android/android_polled_state_config.pbzero.cc
31840 // Intentionally empty (crbug.com/998165)
31841 // gen_amalgamated begin source: gen/protos/perfetto/config/android/packages_list_config.pbzero.cc
31842 // Intentionally empty (crbug.com/998165)
31843 // gen_amalgamated begin source: gen/protos/perfetto/config/ftrace/ftrace_config.pbzero.cc
31844 // Intentionally empty (crbug.com/998165)
31845 // gen_amalgamated begin source: gen/protos/perfetto/config/gpu/gpu_counter_config.pbzero.cc
31846 // Intentionally empty (crbug.com/998165)
31847 // gen_amalgamated begin source: gen/protos/perfetto/config/gpu/vulkan_memory_config.pbzero.cc
31848 // Intentionally empty (crbug.com/998165)
31849 // gen_amalgamated begin source: gen/protos/perfetto/config/inode_file/inode_file_config.pbzero.cc
31850 // Intentionally empty (crbug.com/998165)
31851 // gen_amalgamated begin source: gen/protos/perfetto/config/interceptors/console_config.pbzero.cc
31852 // Intentionally empty (crbug.com/998165)
31853 // gen_amalgamated begin source: gen/protos/perfetto/config/power/android_power_config.pbzero.cc
31854 // Intentionally empty (crbug.com/998165)
31855 // gen_amalgamated begin source: gen/protos/perfetto/config/process_stats/process_stats_config.pbzero.cc
31856 // Intentionally empty (crbug.com/998165)
31857 // gen_amalgamated begin source: gen/protos/perfetto/config/profiling/heapprofd_config.pbzero.cc
31858 // Intentionally empty (crbug.com/998165)
31859 // gen_amalgamated begin source: gen/protos/perfetto/config/profiling/java_hprof_config.pbzero.cc
31860 // Intentionally empty (crbug.com/998165)
31861 // gen_amalgamated begin source: gen/protos/perfetto/config/profiling/perf_event_config.pbzero.cc
31862 // Intentionally empty (crbug.com/998165)
31863 // gen_amalgamated begin source: gen/protos/perfetto/config/sys_stats/sys_stats_config.pbzero.cc
31864 // Intentionally empty (crbug.com/998165)
31865 // gen_amalgamated begin source: gen/protos/perfetto/config/track_event/track_event_config.pbzero.cc
31866 // Intentionally empty (crbug.com/998165)
31867 // gen_amalgamated begin source: gen/protos/perfetto/config/chrome/chrome_config.pbzero.cc
31868 // Intentionally empty (crbug.com/998165)
31869 // gen_amalgamated begin source: gen/protos/perfetto/config/data_source_config.pbzero.cc
31870 // Intentionally empty (crbug.com/998165)
31871 // gen_amalgamated begin source: gen/protos/perfetto/config/interceptor_config.pbzero.cc
31872 // Intentionally empty (crbug.com/998165)
31873 // gen_amalgamated begin source: gen/protos/perfetto/config/stress_test_config.pbzero.cc
31874 // Intentionally empty (crbug.com/998165)
31875 // gen_amalgamated begin source: gen/protos/perfetto/config/test_config.pbzero.cc
31876 // Intentionally empty (crbug.com/998165)
31877 // gen_amalgamated begin source: gen/protos/perfetto/config/trace_config.pbzero.cc
31878 // Intentionally empty (crbug.com/998165)
31879 // gen_amalgamated begin source: gen/protos/perfetto/trace/clock_snapshot.pbzero.cc
31880 // Intentionally empty (crbug.com/998165)
31881 // gen_amalgamated begin source: gen/protos/perfetto/trace/trigger.pbzero.cc
31882 // Intentionally empty (crbug.com/998165)
31883 // gen_amalgamated begin source: gen/protos/perfetto/trace/system_info.pbzero.cc
31884 // Intentionally empty (crbug.com/998165)
31885 // gen_amalgamated begin source: gen/protos/perfetto/trace/android/android_log.pbzero.cc
31886 // Intentionally empty (crbug.com/998165)
31887 // gen_amalgamated begin source: gen/protos/perfetto/trace/android/frame_timeline_event.pbzero.cc
31888 // Intentionally empty (crbug.com/998165)
31889 // gen_amalgamated begin source: gen/protos/perfetto/trace/android/gpu_mem_event.pbzero.cc
31890 // Intentionally empty (crbug.com/998165)
31891 // gen_amalgamated begin source: gen/protos/perfetto/trace/android/graphics_frame_event.pbzero.cc
31892 // Intentionally empty (crbug.com/998165)
31893 // gen_amalgamated begin source: gen/protos/perfetto/trace/android/initial_display_state.pbzero.cc
31894 // Intentionally empty (crbug.com/998165)
31895 // gen_amalgamated begin source: gen/protos/perfetto/trace/android/packages_list.pbzero.cc
31896 // Intentionally empty (crbug.com/998165)
31897 // gen_amalgamated begin source: gen/protos/perfetto/trace/chrome/chrome_benchmark_metadata.pbzero.cc
31898 // Intentionally empty (crbug.com/998165)
31899 // gen_amalgamated begin source: gen/protos/perfetto/trace/chrome/chrome_metadata.pbzero.cc
31900 // Intentionally empty (crbug.com/998165)
31901 // gen_amalgamated begin source: gen/protos/perfetto/trace/chrome/chrome_trace_event.pbzero.cc
31902 // Intentionally empty (crbug.com/998165)
31903 // gen_amalgamated begin source: gen/protos/perfetto/trace/filesystem/inode_file_map.pbzero.cc
31904 // Intentionally empty (crbug.com/998165)
31905 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ftrace_event.pbzero.cc
31906 // Intentionally empty (crbug.com/998165)
31907 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.cc
31908 // Intentionally empty (crbug.com/998165)
31909 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ftrace_stats.pbzero.cc
31910 // Intentionally empty (crbug.com/998165)
31911 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/test_bundle_wrapper.pbzero.cc
31912 // Intentionally empty (crbug.com/998165)
31913 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/generic.pbzero.cc
31914 // Intentionally empty (crbug.com/998165)
31915 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/binder.pbzero.cc
31916 // Intentionally empty (crbug.com/998165)
31917 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/block.pbzero.cc
31918 // Intentionally empty (crbug.com/998165)
31919 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/cgroup.pbzero.cc
31920 // Intentionally empty (crbug.com/998165)
31921 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/clk.pbzero.cc
31922 // Intentionally empty (crbug.com/998165)
31923 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/compaction.pbzero.cc
31924 // Intentionally empty (crbug.com/998165)
31925 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/cpuhp.pbzero.cc
31926 // Intentionally empty (crbug.com/998165)
31927 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/dmabuf_heap.pbzero.cc
31928 // Intentionally empty (crbug.com/998165)
31929 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/dpu.pbzero.cc
31930 // Intentionally empty (crbug.com/998165)
31931 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ext4.pbzero.cc
31932 // Intentionally empty (crbug.com/998165)
31933 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/f2fs.pbzero.cc
31934 // Intentionally empty (crbug.com/998165)
31935 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/fastrpc.pbzero.cc
31936 // Intentionally empty (crbug.com/998165)
31937 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/fence.pbzero.cc
31938 // Intentionally empty (crbug.com/998165)
31939 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/filemap.pbzero.cc
31940 // Intentionally empty (crbug.com/998165)
31941 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ftrace.pbzero.cc
31942 // Intentionally empty (crbug.com/998165)
31943 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/g2d.pbzero.cc
31944 // Intentionally empty (crbug.com/998165)
31945 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/gpu_mem.pbzero.cc
31946 // Intentionally empty (crbug.com/998165)
31947 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/i2c.pbzero.cc
31948 // Intentionally empty (crbug.com/998165)
31949 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ion.pbzero.cc
31950 // Intentionally empty (crbug.com/998165)
31951 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ipi.pbzero.cc
31952 // Intentionally empty (crbug.com/998165)
31953 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/irq.pbzero.cc
31954 // Intentionally empty (crbug.com/998165)
31955 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/kmem.pbzero.cc
31956 // Intentionally empty (crbug.com/998165)
31957 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/lowmemorykiller.pbzero.cc
31958 // Intentionally empty (crbug.com/998165)
31959 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/mali.pbzero.cc
31960 // Intentionally empty (crbug.com/998165)
31961 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/mdss.pbzero.cc
31962 // Intentionally empty (crbug.com/998165)
31963 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/mm_event.pbzero.cc
31964 // Intentionally empty (crbug.com/998165)
31965 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/oom.pbzero.cc
31966 // Intentionally empty (crbug.com/998165)
31967 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/power.pbzero.cc
31968 // Intentionally empty (crbug.com/998165)
31969 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/raw_syscalls.pbzero.cc
31970 // Intentionally empty (crbug.com/998165)
31971 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/regulator.pbzero.cc
31972 // Intentionally empty (crbug.com/998165)
31973 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/sched.pbzero.cc
31974 // Intentionally empty (crbug.com/998165)
31975 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/scm.pbzero.cc
31976 // Intentionally empty (crbug.com/998165)
31977 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/sde.pbzero.cc
31978 // Intentionally empty (crbug.com/998165)
31979 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/signal.pbzero.cc
31980 // Intentionally empty (crbug.com/998165)
31981 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/sync.pbzero.cc
31982 // Intentionally empty (crbug.com/998165)
31983 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/systrace.pbzero.cc
31984 // Intentionally empty (crbug.com/998165)
31985 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/task.pbzero.cc
31986 // Intentionally empty (crbug.com/998165)
31987 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/thermal.pbzero.cc
31988 // Intentionally empty (crbug.com/998165)
31989 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/vmscan.pbzero.cc
31990 // Intentionally empty (crbug.com/998165)
31991 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/workqueue.pbzero.cc
31992 // Intentionally empty (crbug.com/998165)
31993 // gen_amalgamated begin source: gen/protos/perfetto/trace/perfetto/perfetto_metatrace.pbzero.cc
31994 // Intentionally empty (crbug.com/998165)
31995 // gen_amalgamated begin source: gen/protos/perfetto/trace/perfetto/tracing_service_event.pbzero.cc
31996 // Intentionally empty (crbug.com/998165)
31997 // gen_amalgamated begin source: gen/protos/perfetto/trace/power/android_energy_estimation_breakdown.pbzero.cc
31998 // Intentionally empty (crbug.com/998165)
31999 // gen_amalgamated begin source: gen/protos/perfetto/trace/power/battery_counters.pbzero.cc
32000 // Intentionally empty (crbug.com/998165)
32001 // gen_amalgamated begin source: gen/protos/perfetto/trace/power/power_rails.pbzero.cc
32002 // Intentionally empty (crbug.com/998165)
32003 // gen_amalgamated begin source: gen/protos/perfetto/trace/ps/process_stats.pbzero.cc
32004 // Intentionally empty (crbug.com/998165)
32005 // gen_amalgamated begin source: gen/protos/perfetto/trace/ps/process_tree.pbzero.cc
32006 // Intentionally empty (crbug.com/998165)
32007 // gen_amalgamated begin source: gen/protos/perfetto/trace/sys_stats/sys_stats.pbzero.cc
32008 // Intentionally empty (crbug.com/998165)
32009 // gen_amalgamated begin source: gen/protos/perfetto/trace/system_info/cpu_info.pbzero.cc
32010 // Intentionally empty (crbug.com/998165)
32011 // gen_amalgamated begin source: gen/protos/perfetto/trace/trace_packet_defaults.pbzero.cc
32012 // Intentionally empty (crbug.com/998165)
32013 // gen_amalgamated begin source: gen/protos/perfetto/trace/test_event.pbzero.cc
32014 // Intentionally empty (crbug.com/998165)
32015 // gen_amalgamated begin source: gen/protos/perfetto/trace/test_extensions.pbzero.cc
32016 // Intentionally empty (crbug.com/998165)
32017 // gen_amalgamated begin source: gen/protos/perfetto/trace/trace_packet.pbzero.cc
32018 // Intentionally empty (crbug.com/998165)
32019 // gen_amalgamated begin source: gen/protos/perfetto/trace/trace.pbzero.cc
32020 // Intentionally empty (crbug.com/998165)
32021 // gen_amalgamated begin source: gen/protos/perfetto/trace/extension_descriptor.pbzero.cc
32022 // Intentionally empty (crbug.com/998165)
32023 // gen_amalgamated begin source: gen/protos/perfetto/trace/memory_graph.pbzero.cc
32024 // Intentionally empty (crbug.com/998165)
32025 // gen_amalgamated begin source: gen/protos/perfetto/trace/ui_state.pbzero.cc
32026 // Intentionally empty (crbug.com/998165)
32027 // gen_amalgamated begin source: src/tracing/trace_writer_base.cc
32028 /*
32029  * Copyright (C) 2019 The Android Open Source Project
32030  *
32031  * Licensed under the Apache License, Version 2.0 (the "License");
32032  * you may not use this file except in compliance with the License.
32033  * You may obtain a copy of the License at
32034  *
32035  *      http://www.apache.org/licenses/LICENSE-2.0
32036  *
32037  * Unless required by applicable law or agreed to in writing, software
32038  * distributed under the License is distributed on an "AS IS" BASIS,
32039  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
32040  * See the License for the specific language governing permissions and
32041  * limitations under the License.
32042  */
32043 
32044 // gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
32045 
32046 namespace perfetto {
32047 
32048 // This destructor needs to be defined in a dedicated translation unit and
32049 // cannot be merged together with the other ones in virtual_destructors.cc.
32050 // This is because trace_writer_base.h/cc  is part of a separate target
32051 // (src/public:common) that is linked also by other part of the codebase.
32052 
32053 TraceWriterBase::~TraceWriterBase() = default;
32054 
32055 }  // namespace perfetto
32056 // gen_amalgamated begin source: src/tracing/core/id_allocator.cc
32057 // gen_amalgamated begin header: src/tracing/core/id_allocator.h
32058 /*
32059  * Copyright (C) 2017 The Android Open Source Project
32060  *
32061  * Licensed under the Apache License, Version 2.0 (the "License");
32062  * you may not use this file except in compliance with the License.
32063  * You may obtain a copy of the License at
32064  *
32065  *      http://www.apache.org/licenses/LICENSE-2.0
32066  *
32067  * Unless required by applicable law or agreed to in writing, software
32068  * distributed under the License is distributed on an "AS IS" BASIS,
32069  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
32070  * See the License for the specific language governing permissions and
32071  * limitations under the License.
32072  */
32073 
32074 #ifndef SRC_TRACING_CORE_ID_ALLOCATOR_H_
32075 #define SRC_TRACING_CORE_ID_ALLOCATOR_H_
32076 
32077 #include <stdint.h>
32078 
32079 #include <type_traits>
32080 #include <vector>
32081 
32082 namespace perfetto {
32083 
32084 // Handles assigment of IDs (int types) from a fixed-size pool.
32085 // Zero is not considered a valid ID.
32086 // The base class takes always a uint32_t and the derived class casts and checks
32087 // bounds at compile time. This is to avoid bloating code with different
32088 // instances of the main class for each size.
32089 class IdAllocatorGeneric {
32090  public:
32091   // |max_id| is inclusive.
32092   explicit IdAllocatorGeneric(uint32_t max_id);
32093   ~IdAllocatorGeneric();
32094 
32095   // Returns an ID in the range [1, max_id] or 0 if no more ids are available.
32096   uint32_t AllocateGeneric();
32097   void FreeGeneric(uint32_t);
32098 
32099   bool IsEmpty() const;
32100 
32101  private:
32102   IdAllocatorGeneric(const IdAllocatorGeneric&) = delete;
32103   IdAllocatorGeneric& operator=(const IdAllocatorGeneric&) = delete;
32104 
32105   const uint32_t max_id_;
32106   uint32_t last_id_ = 0;
32107   std::vector<bool> ids_;
32108 };
32109 
32110 template <typename T = uint32_t>
32111 class IdAllocator : public IdAllocatorGeneric {
32112  public:
IdAllocator(T end)32113   explicit IdAllocator(T end) : IdAllocatorGeneric(end) {
32114     static_assert(std::is_integral<T>::value && std::is_unsigned<T>::value,
32115                   "T must be an unsigned integer");
32116     static_assert(sizeof(T) <= sizeof(uint32_t), "T is too big");
32117   }
32118 
Allocate()32119   T Allocate() { return static_cast<T>(AllocateGeneric()); }
Free(T id)32120   void Free(T id) { FreeGeneric(id); }
32121 };
32122 
32123 }  // namespace perfetto
32124 
32125 #endif  // SRC_TRACING_CORE_ID_ALLOCATOR_H_
32126 /*
32127  * Copyright (C) 2017 The Android Open Source Project
32128  *
32129  * Licensed under the Apache License, Version 2.0 (the "License");
32130  * you may not use this file except in compliance with the License.
32131  * You may obtain a copy of the License at
32132  *
32133  *      http://www.apache.org/licenses/LICENSE-2.0
32134  *
32135  * Unless required by applicable law or agreed to in writing, software
32136  * distributed under the License is distributed on an "AS IS" BASIS,
32137  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
32138  * See the License for the specific language governing permissions and
32139  * limitations under the License.
32140  */
32141 
32142 // gen_amalgamated expanded: #include "src/tracing/core/id_allocator.h"
32143 
32144 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
32145 
32146 namespace perfetto {
32147 
IdAllocatorGeneric(uint32_t max_id)32148 IdAllocatorGeneric::IdAllocatorGeneric(uint32_t max_id) : max_id_(max_id) {
32149   PERFETTO_DCHECK(max_id > 1);
32150 }
32151 
32152 IdAllocatorGeneric::~IdAllocatorGeneric() = default;
32153 
AllocateGeneric()32154 uint32_t IdAllocatorGeneric::AllocateGeneric() {
32155   for (uint32_t ignored = 1; ignored <= max_id_; ignored++) {
32156     last_id_ = last_id_ < max_id_ ? last_id_ + 1 : 1;
32157     const auto id = last_id_;
32158 
32159     // 0 is never a valid ID. So if we are looking for |id| == N and there are
32160     // N or less elements in the vector, they must necessarily be all < N.
32161     // e.g. if |id| == 4 and size() == 4, the vector will contain IDs 0,1,2,3.
32162     if (id >= ids_.size()) {
32163       ids_.resize(id + 1);
32164       ids_[id] = true;
32165       return id;
32166     }
32167 
32168     if (!ids_[id]) {
32169       ids_[id] = true;
32170       return id;
32171     }
32172   }
32173   return 0;
32174 }
32175 
FreeGeneric(uint32_t id)32176 void IdAllocatorGeneric::FreeGeneric(uint32_t id) {
32177   if (id == 0 || id >= ids_.size() || !ids_[id]) {
32178     PERFETTO_DFATAL("Invalid id.");
32179     return;
32180   }
32181   ids_[id] = false;
32182 }
32183 
IsEmpty() const32184 bool IdAllocatorGeneric::IsEmpty() const {
32185   for (const auto id : ids_) {
32186     if (id)
32187       return false;
32188   }
32189   return true;
32190 }
32191 
32192 }  // namespace perfetto
32193 // gen_amalgamated begin source: src/tracing/core/null_trace_writer.cc
32194 // gen_amalgamated begin header: src/tracing/core/null_trace_writer.h
32195 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/trace_writer.h
32196 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/basic_types.h
32197 /*
32198  * Copyright (C) 2017 The Android Open Source Project
32199  *
32200  * Licensed under the Apache License, Version 2.0 (the "License");
32201  * you may not use this file except in compliance with the License.
32202  * You may obtain a copy of the License at
32203  *
32204  *      http://www.apache.org/licenses/LICENSE-2.0
32205  *
32206  * Unless required by applicable law or agreed to in writing, software
32207  * distributed under the License is distributed on an "AS IS" BASIS,
32208  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
32209  * See the License for the specific language governing permissions and
32210  * limitations under the License.
32211  */
32212 
32213 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_BASIC_TYPES_H_
32214 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_BASIC_TYPES_H_
32215 
32216 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
32217 
32218 #include <stddef.h>
32219 #include <stdint.h>
32220 #include <sys/types.h>
32221 
32222 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
32223 using uid_t = unsigned int;
32224 #endif
32225 
32226 namespace perfetto {
32227 
32228 // Unique within the scope of the tracing service.
32229 using TracingSessionID = uint64_t;
32230 
32231 // Unique within the scope of the tracing service.
32232 using ProducerID = uint16_t;
32233 
32234 // Unique within the scope of the tracing service.
32235 using DataSourceInstanceID = uint64_t;
32236 
32237 // Unique within the scope of a Producer.
32238 using WriterID = uint16_t;
32239 
32240 // Unique within the scope of the tracing service.
32241 using FlushRequestID = uint64_t;
32242 
32243 // We need one FD per producer and we are not going to be able to keep > 64k FDs
32244 // open in the service.
32245 static constexpr ProducerID kMaxProducerID = static_cast<ProducerID>(-1);
32246 
32247 // 1024 Writers per producer seems a resonable bound. This reduces the ability
32248 // to memory-DoS the service by having to keep track of too many writer IDs.
32249 static constexpr WriterID kMaxWriterID = static_cast<WriterID>((1 << 10) - 1);
32250 
32251 // Unique within the scope of a {ProducerID, WriterID} tuple.
32252 using ChunkID = uint32_t;
32253 static constexpr ChunkID kMaxChunkID = static_cast<ChunkID>(-1);
32254 
32255 // Unique within the scope of the tracing service.
32256 using BufferID = uint16_t;
32257 
32258 // Target buffer ID for SharedMemoryArbiter. Values up to max uint16_t are
32259 // equivalent to a bound BufferID. Values above max uint16_t are reservation IDs
32260 // for the target buffer of a startup trace writer. Reservation IDs will be
32261 // translated to actual BufferIDs after they are bound by
32262 // SharedMemoryArbiter::BindStartupTargetBuffer().
32263 using MaybeUnboundBufferID = uint32_t;
32264 
32265 // Keep this in sync with SharedMemoryABI::PageHeader::target_buffer.
32266 static constexpr BufferID kMaxTraceBufferID = static_cast<BufferID>(-1);
32267 
32268 // Unique within the scope of a tracing session.
32269 using PacketSequenceID = uint32_t;
32270 // Used for extra packets emitted by the service, such as statistics.
32271 static constexpr PacketSequenceID kServicePacketSequenceID = 1;
32272 static constexpr PacketSequenceID kMaxPacketSequenceID =
32273     static_cast<PacketSequenceID>(-1);
32274 
32275 constexpr uid_t kInvalidUid = static_cast<uid_t>(-1);
32276 
32277 constexpr uint32_t kDefaultFlushTimeoutMs = 5000;
32278 
32279 }  // namespace perfetto
32280 
32281 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_BASIC_TYPES_H_
32282 /*
32283  * Copyright (C) 2017 The Android Open Source Project
32284  *
32285  * Licensed under the Apache License, Version 2.0 (the "License");
32286  * you may not use this file except in compliance with the License.
32287  * You may obtain a copy of the License at
32288  *
32289  *      http://www.apache.org/licenses/LICENSE-2.0
32290  *
32291  * Unless required by applicable law or agreed to in writing, software
32292  * distributed under the License is distributed on an "AS IS" BASIS,
32293  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
32294  * See the License for the specific language governing permissions and
32295  * limitations under the License.
32296  */
32297 
32298 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_WRITER_H_
32299 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_WRITER_H_
32300 
32301 #include <functional>
32302 
32303 // gen_amalgamated expanded: #include "perfetto/base/export.h"
32304 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
32305 // gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
32306 // gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
32307 
32308 namespace perfetto {
32309 
32310 namespace protos {
32311 namespace pbzero {
32312 class TracePacket;
32313 }  // namespace pbzero
32314 }  // namespace protos
32315 
32316 // This is a single-thread write interface that allows to write protobufs
32317 // directly into the tracing shared buffer without making any copies.
32318 // It takes care of acquiring and releasing chunks from the
32319 // SharedMemoryArbiter and splitting protos over chunks.
32320 // The idea is that each data source creates one (or more) TraceWriter for each
32321 // thread it wants to write from. Each TraceWriter will get its own dedicated
32322 // chunk and will write into the shared buffer without any locking most of the
32323 // time. Locking will happen only when a chunk is exhausted and a new one is
32324 // acquired from the arbiter.
32325 
32326 // TODO: TraceWriter needs to keep the shared memory buffer alive (refcount?).
32327 // Otherwise if the shared memory buffer goes away (e.g. the Service crashes)
32328 // the TraceWriter will keep writing into unmapped memory.
32329 
32330 class PERFETTO_EXPORT TraceWriter : public TraceWriterBase {
32331  public:
32332   using TracePacketHandle =
32333       protozero::MessageHandle<protos::pbzero::TracePacket>;
32334 
32335   TraceWriter();
32336   ~TraceWriter() override;
32337 
32338   // Returns a handle to the root proto message for the trace. The message will
32339   // be finalized either by calling directly handle.Finalize() or by letting the
32340   // handle go out of scope. The returned handle can be std::move()'d but cannot
32341   // be used after either: (i) the TraceWriter instance is destroyed, (ii) a
32342   // subsequence NewTracePacket() call is made on the same TraceWriter instance.
32343   // The returned packet handle is always valid, but note that, when using
32344   // BufferExhaustedPolicy::kDrop and the SMB is exhausted, it may be assigned
32345   // a garbage chunk and any trace data written into it will be lost. For more
32346   // details on buffer size choices: https://perfetto.dev/docs/concepts/buffers.
32347   TracePacketHandle NewTracePacket() override = 0;
32348 
32349   // Commits the data pending for the current chunk into the shared memory
32350   // buffer and sends a CommitDataRequest() to the service. This can be called
32351   // only if the handle returned by NewTracePacket() has been destroyed (i.e. we
32352   // cannot Flush() while writing a TracePacket).
32353   // Note: Flush() also happens implicitly when destroying the TraceWriter.
32354   // |callback| is an optional callback. When non-null it will request the
32355   // service to ACK the flush and will be invoked after the service has
32356   // acknowledged it. The callback might be NEVER INVOKED if the service crashes
32357   // or the IPC connection is dropped. The callback should be used only by tests
32358   // and best-effort features (logging).
32359   // TODO(primiano): right now the |callback| will be called on the IPC thread.
32360   // This is fine in the current single-thread scenario, but long-term
32361   // trace_writer_impl.cc should be smarter and post it on the right thread.
32362   void Flush(std::function<void()> callback = {}) override = 0;
32363 
32364   virtual WriterID writer_id() const = 0;
32365 
32366   // Bytes written since creation. Is not reset when new chunks are acquired.
32367   virtual uint64_t written() const override = 0;
32368 
32369  private:
32370   TraceWriter(const TraceWriter&) = delete;
32371   TraceWriter& operator=(const TraceWriter&) = delete;
32372 };
32373 
32374 }  // namespace perfetto
32375 
32376 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_WRITER_H_
32377 /*
32378  * Copyright (C) 2018 The Android Open Source Project
32379  *
32380  * Licensed under the Apache License, Version 2.0 (the "License");
32381  * you may not use this file except in compliance with the License.
32382  * You may obtain a copy of the License at
32383  *
32384  *      http://www.apache.org/licenses/LICENSE-2.0
32385  *
32386  * Unless required by applicable law or agreed to in writing, software
32387  * distributed under the License is distributed on an "AS IS" BASIS,
32388  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
32389  * See the License for the specific language governing permissions and
32390  * limitations under the License.
32391  */
32392 
32393 #ifndef SRC_TRACING_CORE_NULL_TRACE_WRITER_H_
32394 #define SRC_TRACING_CORE_NULL_TRACE_WRITER_H_
32395 
32396 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
32397 // gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
32398 // gen_amalgamated expanded: #include "perfetto/protozero/root_message.h"
32399 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_null_delegate.h"
32400 
32401 namespace perfetto {
32402 
32403 // A specialization of TraceWriter which no-ops all the writes routing them
32404 // into a fixed region of memory
32405 // See //include/perfetto/tracing/core/trace_writer.h for docs.
32406 class NullTraceWriter : public TraceWriter {
32407  public:
32408   NullTraceWriter();
32409   ~NullTraceWriter() override;
32410 
32411   // TraceWriter implementation. See documentation in trace_writer.h.
32412   // TracePacketHandle is defined in trace_writer.h
32413   TracePacketHandle NewTracePacket() override;
32414   void Flush(std::function<void()> callback = {}) override;
32415   WriterID writer_id() const override;
32416   uint64_t written() const override;
32417 
32418  private:
32419   NullTraceWriter(const NullTraceWriter&) = delete;
32420   NullTraceWriter& operator=(const NullTraceWriter&) = delete;
32421 
32422   protozero::ScatteredStreamWriterNullDelegate delegate_;
32423   protozero::ScatteredStreamWriter stream_;
32424 
32425   // The packet returned via NewTracePacket(). Its owned by this class,
32426   // TracePacketHandle has just a pointer to it.
32427   std::unique_ptr<protozero::RootMessage<protos::pbzero::TracePacket>>
32428       cur_packet_;
32429 };
32430 
32431 }  // namespace perfetto
32432 
32433 #endif  // SRC_TRACING_CORE_NULL_TRACE_WRITER_H_
32434 /*
32435  * Copyright (C) 2018 The Android Open Source Project
32436  *
32437  * Licensed under the Apache License, Version 2.0 (the "License");
32438  * you may not use this file except in compliance with the License.
32439  * You may obtain a copy of the License at
32440  *
32441  *      http://www.apache.org/licenses/LICENSE-2.0
32442  *
32443  * Unless required by applicable law or agreed to in writing, software
32444  * distributed under the License is distributed on an "AS IS" BASIS,
32445  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
32446  * See the License for the specific language governing permissions and
32447  * limitations under the License.
32448  */
32449 
32450 // gen_amalgamated expanded: #include "src/tracing/core/null_trace_writer.h"
32451 
32452 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
32453 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
32454 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
32455 
32456 // gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
32457 
32458 namespace perfetto {
32459 
NullTraceWriter()32460 NullTraceWriter::NullTraceWriter() : delegate_(4096), stream_(&delegate_) {
32461   cur_packet_.reset(new protozero::RootMessage<protos::pbzero::TracePacket>());
32462   cur_packet_->Finalize();  // To avoid the DCHECK in NewTracePacket().
32463 }
32464 
~NullTraceWriter()32465 NullTraceWriter::~NullTraceWriter() {}
32466 
Flush(std::function<void ()> callback)32467 void NullTraceWriter::Flush(std::function<void()> callback) {
32468   // Flush() cannot be called in the middle of a TracePacket.
32469   PERFETTO_CHECK(cur_packet_->is_finalized());
32470 
32471   if (callback)
32472     callback();
32473 }
32474 
NewTracePacket()32475 NullTraceWriter::TracePacketHandle NullTraceWriter::NewTracePacket() {
32476   // If we hit this, the caller is calling NewTracePacket() without having
32477   // finalized the previous packet.
32478   PERFETTO_DCHECK(cur_packet_->is_finalized());
32479   cur_packet_->Reset(&stream_);
32480   return TraceWriter::TracePacketHandle(cur_packet_.get());
32481 }
32482 
writer_id() const32483 WriterID NullTraceWriter::writer_id() const {
32484   return 0;
32485 }
32486 
written() const32487 uint64_t NullTraceWriter::written() const {
32488   return 0;
32489 }
32490 
32491 }  // namespace perfetto
32492 // gen_amalgamated begin source: src/tracing/core/shared_memory_abi.cc
32493 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/shared_memory_abi.h
32494 /*
32495  * Copyright (C) 2017 The Android Open Source Project
32496  *
32497  * Licensed under the Apache License, Version 2.0 (the "License");
32498  * you may not use this file except in compliance with the License.
32499  * You may obtain a copy of the License at
32500  *
32501  *      http://www.apache.org/licenses/LICENSE-2.0
32502  *
32503  * Unless required by applicable law or agreed to in writing, software
32504  * distributed under the License is distributed on an "AS IS" BASIS,
32505  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
32506  * See the License for the specific language governing permissions and
32507  * limitations under the License.
32508  */
32509 
32510 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ABI_H_
32511 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ABI_H_
32512 
32513 #include <stddef.h>
32514 #include <stdint.h>
32515 
32516 #include <array>
32517 #include <atomic>
32518 #include <bitset>
32519 #include <thread>
32520 #include <type_traits>
32521 #include <utility>
32522 
32523 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
32524 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
32525 
32526 namespace perfetto {
32527 
32528 // This file defines the binary interface of the memory buffers shared between
32529 // Producer and Service. This is a long-term stable ABI and has to be backwards
32530 // compatible to deal with mismatching Producer and Service versions.
32531 //
32532 // Overview
32533 // --------
32534 // SMB := "Shared Memory Buffer".
32535 // In the most typical case of a multi-process architecture (i.e. Producer and
32536 // Service are hosted by different processes), a Producer means almost always
32537 // a "client process producing data" (almost: in some cases a process might host
32538 // > 1 Producer, if it links two libraries, independent of each other, that both
32539 // use Perfetto tracing).
32540 // The Service has one SMB for each Producer.
32541 // A producer has one or (typically) more data sources. They all share the same
32542 // SMB.
32543 // The SMB is a staging area to decouple data sources living in the Producer
32544 // and allow them to do non-blocking async writes.
32545 // The SMB is *not* the ultimate logging buffer seen by the Consumer. That one
32546 // is larger (~MBs) and not shared with Producers.
32547 // Each SMB is small, typically few KB. Its size is configurable by the producer
32548 // within a max limit of ~MB (see kMaxShmSize in tracing_service_impl.cc).
32549 // The SMB is partitioned into fixed-size Page(s). The size of the Pages are
32550 // determined by each Producer at connection time and cannot be changed.
32551 // Hence, different producers can have SMB(s) that have a different Page size
32552 // from each other, but the page size will be constant throughout all the
32553 // lifetime of the SMB.
32554 // Page(s) are partitioned by the Producer into variable size Chunk(s):
32555 //
32556 // +------------+      +--------------------------+
32557 // | Producer 1 |  <-> |      SMB 1 [~32K - 1MB]  |
32558 // +------------+      +--------+--------+--------+
32559 //                     |  Page  |  Page  |  Page  |
32560 //                     +--------+--------+--------+
32561 //                     | Chunk  |        | Chunk  |
32562 //                     +--------+  Chunk +--------+ <----+
32563 //                     | Chunk  |        | Chunk  |      |
32564 //                     +--------+--------+--------+      +---------------------+
32565 //                                                       |       Service       |
32566 // +------------+      +--------------------------+      +---------------------+
32567 // | Producer 2 |  <-> |      SMB 2 [~32K - 1MB]  |     /| large ring buffers  |
32568 // +------------+      +--------+--------+--------+ <--+ | (100K - several MB) |
32569 //                     |  Page  |  Page  |  Page  |      +---------------------+
32570 //                     +--------+--------+--------+
32571 //                     | Chunk  |        | Chunk  |
32572 //                     +--------+  Chunk +--------+
32573 //                     | Chunk  |        | Chunk  |
32574 //                     +--------+--------+--------+
32575 //
32576 // * Sizes of both SMB and ring buffers are purely indicative and decided at
32577 // configuration time by the Producer (for SMB sizes) and the Consumer (for the
32578 // final ring buffer size).
32579 
32580 // Page
32581 // ----
32582 // A page is a portion of the shared memory buffer and defines the granularity
32583 // of the interaction between the Producer and tracing Service. When scanning
32584 // the shared memory buffer to determine if something should be moved to the
32585 // central logging buffers, the Service most of the times looks at and moves
32586 // whole pages. Similarly, the Producer sends an IPC to invite the Service to
32587 // drain the shared memory buffer only when a whole page is filled.
32588 // Having fixed the total SMB size (hence the total memory overhead), the page
32589 // size is a triangular tradeoff between:
32590 // 1) IPC traffic: smaller pages -> more IPCs.
32591 // 2) Producer lock freedom: larger pages -> larger chunks -> data sources can
32592 //    write more data without needing to swap chunks and synchronize.
32593 // 3) Risk of write-starving the SMB: larger pages -> higher chance that the
32594 //    Service won't manage to drain them and the SMB remains full.
32595 // The page size, on the other side, has no implications on wasted memory due to
32596 // fragmentations (see Chunk below).
32597 // The size of the page is chosen by the Service at connection time and stays
32598 // fixed throughout all the lifetime of the Producer. Different producers (i.e.
32599 // ~ different client processes) can use different page sizes.
32600 // The page size must be an integer multiple of 4k (this is to allow VM page
32601 // stealing optimizations) and obviously has to be an integer divisor of the
32602 // total SMB size.
32603 
32604 // Chunk
32605 // -----
32606 // A chunk is a portion of a Page which is written and handled by a Producer.
32607 // A chunk contains a linear sequence of TracePacket(s) (the root proto).
32608 // A chunk cannot be written concurrently by two data sources. Protobufs must be
32609 // encoded as contiguous byte streams and cannot be interleaved. Therefore, on
32610 // the Producer side, a chunk is almost always owned exclusively by one thread
32611 // (% extremely peculiar slow-path cases).
32612 // Chunks are essentially single-writer single-thread lock-free arenas. Locking
32613 // happens only when a Chunk is full and a new one needs to be acquired.
32614 // Locking happens only within the scope of a Producer process. There is no
32615 // inter-process locking. The Producer cannot lock the Service and viceversa.
32616 // In the worst case, any of the two can starve the SMB, by marking all chunks
32617 // as either being read or written. But that has the only side effect of
32618 // losing the trace data.
32619 // The Producer can decide to partition each page into a number of limited
32620 // configurations (e.g., 1 page == 1 chunk, 1 page == 2 chunks and so on).
32621 
32622 // TracePacket
32623 // -----------
32624 // Is the atom of tracing. Putting aside pages and chunks a trace is merely a
32625 // sequence of TracePacket(s). TracePacket is the root protobuf message.
32626 // A TracePacket can span across several chunks (hence even across several
32627 // pages). A TracePacket can therefore be >> chunk size, >> page size and even
32628 // >> SMB size. The Chunk header carries metadata to deal with the TracePacket
32629 // splitting case.
32630 
32631 // Use only explicitly-sized types below. DO NOT use size_t or any architecture
32632 // dependent size (e.g. size_t) in the struct fields. This buffer will be read
32633 // and written by processes that have a different bitness in the same OS.
32634 // Instead it's fine to assume little-endianess. Big-endian is a dream we are
32635 // not currently pursuing.
32636 
32637 class SharedMemoryABI {
32638  public:
32639   static constexpr size_t kMinPageSize = 4 * 1024;
32640 
32641   // This is due to Chunk::size being 16 bits.
32642   static constexpr size_t kMaxPageSize = 64 * 1024;
32643 
32644   // "14" is the max number that can be encoded in a 32 bit atomic word using
32645   // 2 state bits per Chunk and leaving 4 bits for the page layout.
32646   // See PageLayout below.
32647   static constexpr size_t kMaxChunksPerPage = 14;
32648 
32649   // Each TracePacket in the Chunk is prefixed by a 4 bytes redundant VarInt
32650   // (see proto_utils.h) stating its size.
32651   static constexpr size_t kPacketHeaderSize = 4;
32652 
32653   // TraceWriter specifies this invalid packet/fragment size to signal to the
32654   // service that a packet should be discarded, because the TraceWriter couldn't
32655   // write its remaining fragments (e.g. because the SMB was exhausted).
32656   static constexpr size_t kPacketSizeDropPacket =
32657       protozero::proto_utils::kMaxMessageLength;
32658 
32659   // Chunk states and transitions:
32660   //    kChunkFree  <----------------+
32661   //         |  (Producer)           |
32662   //         V                       |
32663   //  kChunkBeingWritten             |
32664   //         |  (Producer)           |
32665   //         V                       |
32666   //  kChunkComplete                 |
32667   //         |  (Service)            |
32668   //         V                       |
32669   //  kChunkBeingRead                |
32670   //        |   (Service)            |
32671   //        +------------------------+
32672   enum ChunkState : uint32_t {
32673     // The Chunk is free. The Service shall never touch it, the Producer can
32674     // acquire it and transition it into kChunkBeingWritten.
32675     kChunkFree = 0,
32676 
32677     // The Chunk is being used by the Producer and is not complete yet.
32678     // The Service shall never touch kChunkBeingWritten pages.
32679     kChunkBeingWritten = 1,
32680 
32681     // The Service is moving the page into its non-shared ring buffer. The
32682     // Producer shall never touch kChunkBeingRead pages.
32683     kChunkBeingRead = 2,
32684 
32685     // The Producer is done writing the page and won't touch it again. The
32686     // Service can now move it to its non-shared ring buffer.
32687     // kAllChunksComplete relies on this being == 3.
32688     kChunkComplete = 3,
32689   };
32690   static constexpr const char* kChunkStateStr[] = {"Free", "BeingWritten",
32691                                                    "BeingRead", "Complete"};
32692 
32693   enum PageLayout : uint32_t {
32694     // The page is fully free and has not been partitioned yet.
32695     kPageNotPartitioned = 0,
32696 
32697     // TODO(primiano): Aligning a chunk @ 16 bytes could allow to use faster
32698     // intrinsics based on quad-word moves. Do the math and check what is the
32699     // fragmentation loss.
32700 
32701     // align4(X) := the largest integer N s.t. (N % 4) == 0 && N <= X.
32702     // 8 == sizeof(PageHeader).
32703     kPageDiv1 = 1,   // Only one chunk of size: PAGE_SIZE - 8.
32704     kPageDiv2 = 2,   // Two chunks of size: align4((PAGE_SIZE - 8) / 2).
32705     kPageDiv4 = 3,   // Four chunks of size: align4((PAGE_SIZE - 8) / 4).
32706     kPageDiv7 = 4,   // Seven chunks of size: align4((PAGE_SIZE - 8) / 7).
32707     kPageDiv14 = 5,  // Fourteen chunks of size: align4((PAGE_SIZE - 8) / 14).
32708 
32709     // The rationale for 7 and 14 above is to maximize the page usage for the
32710     // likely case of |page_size| == 4096:
32711     // (((4096 - 8) / 14) % 4) == 0, while (((4096 - 8) / 16 % 4)) == 3. So
32712     // Div16 would waste 3 * 16 = 48 bytes per page for chunk alignment gaps.
32713 
32714     kPageDivReserved1 = 6,
32715     kPageDivReserved2 = 7,
32716     kNumPageLayouts = 8,
32717   };
32718 
32719   // Keep this consistent with the PageLayout enum above.
32720   static constexpr uint32_t kNumChunksForLayout[] = {0, 1, 2, 4, 7, 14, 0, 0};
32721 
32722   // Layout of a Page.
32723   // +===================================================+
32724   // | Page header [8 bytes]                             |
32725   // | Tells how many chunks there are, how big they are |
32726   // | and their state (free, read, write, complete).    |
32727   // +===================================================+
32728   // +***************************************************+
32729   // | Chunk #0 header [8 bytes]                         |
32730   // | Tells how many packets there are and whether the  |
32731   // | whether the 1st and last ones are fragmented.     |
32732   // | Also has a chunk id to reassemble fragments.    |
32733   // +***************************************************+
32734   // +---------------------------------------------------+
32735   // | Packet #0 size [varint, up to 4 bytes]            |
32736   // + - - - - - - - - - - - - - - - - - - - - - - - - - +
32737   // | Packet #0 payload                                 |
32738   // | A TracePacket protobuf message                    |
32739   // +---------------------------------------------------+
32740   //                         ...
32741   // + . . . . . . . . . . . . . . . . . . . . . . . . . +
32742   // |      Optional padding to maintain aligment        |
32743   // + . . . . . . . . . . . . . . . . . . . . . . . . . +
32744   // +---------------------------------------------------+
32745   // | Packet #N size [varint, up to 4 bytes]            |
32746   // + - - - - - - - - - - - - - - - - - - - - - - - - - +
32747   // | Packet #N payload                                 |
32748   // | A TracePacket protobuf message                    |
32749   // +---------------------------------------------------+
32750   //                         ...
32751   // +***************************************************+
32752   // | Chunk #M header [8 bytes]                         |
32753   //                         ...
32754 
32755   // Alignment applies to start offset only. The Chunk size is *not* aligned.
32756   static constexpr uint32_t kChunkAlignment = 4;
32757   static constexpr uint32_t kChunkShift = 2;
32758   static constexpr uint32_t kChunkMask = 0x3;
32759   static constexpr uint32_t kLayoutMask = 0x70000000;
32760   static constexpr uint32_t kLayoutShift = 28;
32761   static constexpr uint32_t kAllChunksMask = 0x0FFFFFFF;
32762 
32763   // This assumes that kChunkComplete == 3.
32764   static constexpr uint32_t kAllChunksComplete = 0x0FFFFFFF;
32765   static constexpr uint32_t kAllChunksFree = 0;
32766   static constexpr size_t kInvalidPageIdx = static_cast<size_t>(-1);
32767 
32768   // There is one page header per page, at the beginning of the page.
32769   struct PageHeader {
32770     // |layout| bits:
32771     // [31] [30:28] [27:26] ... [1:0]
32772     //  |      |       |     |    |
32773     //  |      |       |     |    +---------- ChunkState[0]
32774     //  |      |       |     +--------------- ChunkState[12..1]
32775     //  |      |       +--------------------- ChunkState[13]
32776     //  |      +----------------------------- PageLayout (0 == page fully free)
32777     //  +------------------------------------ Reserved for future use
32778     std::atomic<uint32_t> layout;
32779 
32780     // If we'll ever going to use this in the future it might come handy
32781     // reviving the kPageBeingPartitioned logic (look in git log, it was there
32782     // at some point in the past).
32783     uint32_t reserved;
32784   };
32785 
32786   // There is one Chunk header per chunk (hence PageLayout per page) at the
32787   // beginning of each chunk.
32788   struct ChunkHeader {
32789     enum Flags : uint8_t {
32790       // If set, the first TracePacket in the chunk is partial and continues
32791       // from |chunk_id| - 1 (within the same |writer_id|).
32792       kFirstPacketContinuesFromPrevChunk = 1 << 0,
32793 
32794       // If set, the last TracePacket in the chunk is partial and continues on
32795       // |chunk_id| + 1 (within the same |writer_id|).
32796       kLastPacketContinuesOnNextChunk = 1 << 1,
32797 
32798       // If set, the last (fragmented) TracePacket in the chunk has holes (even
32799       // if the chunk is marked as kChunkComplete) that need to be patched
32800       // out-of-band before the chunk can be read.
32801       kChunkNeedsPatching = 1 << 2,
32802     };
32803 
32804     struct Packets {
32805       // Number of valid TracePacket protobuf messages contained in the chunk.
32806       // Each TracePacket is prefixed by its own size. This field is
32807       // monotonically updated by the Producer with release store semantic when
32808       // the packet at position |count| is started. This last packet may not be
32809       // considered complete until |count| is incremented for the subsequent
32810       // packet or the chunk is completed.
32811       uint16_t count : 10;
32812       static constexpr size_t kMaxCount = (1 << 10) - 1;
32813 
32814       // See Flags above.
32815       uint16_t flags : 6;
32816     };
32817 
32818     // A monotonic counter of the chunk within the scoped of a |writer_id|.
32819     // The tuple (ProducerID, WriterID, ChunkID) allows to figure out if two
32820     // chunks are contiguous (and hence a trace packets spanning across them can
32821     // be glued) or we had some holes due to the ring buffer wrapping.
32822     // This is set only when transitioning from kChunkFree to kChunkBeingWritten
32823     // and remains unchanged throughout the remaining lifetime of the chunk.
32824     std::atomic<uint32_t> chunk_id;
32825 
32826     // ID of the writer, unique within the producer.
32827     // Like |chunk_id|, this is set only when transitioning from kChunkFree to
32828     // kChunkBeingWritten.
32829     std::atomic<uint16_t> writer_id;
32830 
32831     // There is no ProducerID here. The service figures that out from the IPC
32832     // channel, which is unspoofable.
32833 
32834     // Updated with release-store semantics.
32835     std::atomic<Packets> packets;
32836   };
32837 
32838   class Chunk {
32839    public:
32840     Chunk();  // Constructs an invalid chunk.
32841 
32842     // Chunk is move-only, to document the scope of the Acquire/Release
32843     // TryLock operations below.
32844     Chunk(const Chunk&) = delete;
32845     Chunk operator=(const Chunk&) = delete;
32846     Chunk(Chunk&&) noexcept;
32847     Chunk& operator=(Chunk&&);
32848 
begin() const32849     uint8_t* begin() const { return begin_; }
end() const32850     uint8_t* end() const { return begin_ + size_; }
32851 
32852     // Size, including Chunk header.
size() const32853     size_t size() const { return size_; }
32854 
32855     // Begin of the first packet (or packet fragment).
payload_begin() const32856     uint8_t* payload_begin() const { return begin_ + sizeof(ChunkHeader); }
payload_size() const32857     size_t payload_size() const {
32858       PERFETTO_DCHECK(size_ >= sizeof(ChunkHeader));
32859       return size_ - sizeof(ChunkHeader);
32860     }
32861 
is_valid() const32862     bool is_valid() const { return begin_ && size_; }
32863 
32864     // Index of the chunk within the page [0..13] (13 comes from kPageDiv14).
chunk_idx() const32865     uint8_t chunk_idx() const { return chunk_idx_; }
32866 
header()32867     ChunkHeader* header() { return reinterpret_cast<ChunkHeader*>(begin_); }
32868 
writer_id()32869     uint16_t writer_id() {
32870       return header()->writer_id.load(std::memory_order_relaxed);
32871     }
32872 
32873     // Returns the count of packets and the flags with acquire-load semantics.
GetPacketCountAndFlags()32874     std::pair<uint16_t, uint8_t> GetPacketCountAndFlags() {
32875       auto packets = header()->packets.load(std::memory_order_acquire);
32876       const uint16_t packets_count = packets.count;
32877       const uint8_t packets_flags = packets.flags;
32878       return std::make_pair(packets_count, packets_flags);
32879     }
32880 
32881     // Increases |packets.count| with release semantics (note, however, that the
32882     // packet count is incremented *before* starting writing a packet). Returns
32883     // the new packet count. The increment is atomic but NOT race-free (i.e. no
32884     // CAS). Only the Producer is supposed to perform this increment, and it's
32885     // supposed to do that in a thread-safe way (holding a lock). A Chunk cannot
32886     // be shared by multiple Producer threads without locking. The packet count
32887     // is cleared by TryAcquireChunk(), when passing the new header for the
32888     // chunk.
IncrementPacketCount()32889     uint16_t IncrementPacketCount() {
32890       ChunkHeader* chunk_header = header();
32891       auto packets = chunk_header->packets.load(std::memory_order_relaxed);
32892       packets.count++;
32893       chunk_header->packets.store(packets, std::memory_order_release);
32894       return packets.count;
32895     }
32896 
32897     // Increases |packets.count| to the given |packet_count|, but only if
32898     // |packet_count| is larger than the current value of |packets.count|.
32899     // Returns the new packet count. Same atomicity guarantees as
32900     // IncrementPacketCount().
IncreasePacketCountTo(uint16_t packet_count)32901     uint16_t IncreasePacketCountTo(uint16_t packet_count) {
32902       ChunkHeader* chunk_header = header();
32903       auto packets = chunk_header->packets.load(std::memory_order_relaxed);
32904       if (packets.count < packet_count)
32905         packets.count = packet_count;
32906       chunk_header->packets.store(packets, std::memory_order_release);
32907       return packets.count;
32908     }
32909 
32910     // Flags are cleared by TryAcquireChunk(), by passing the new header for
32911     // the chunk, or through ClearNeedsPatchingFlag.
SetFlag(ChunkHeader::Flags flag)32912     void SetFlag(ChunkHeader::Flags flag) {
32913       ChunkHeader* chunk_header = header();
32914       auto packets = chunk_header->packets.load(std::memory_order_relaxed);
32915       packets.flags |= flag;
32916       chunk_header->packets.store(packets, std::memory_order_release);
32917     }
32918 
32919     // This flag can only be cleared by the producer while it is still holding
32920     // on to the chunk - i.e. while the chunk is still in state
32921     // ChunkState::kChunkBeingWritten and hasn't been transitioned to
32922     // ChunkState::kChunkComplete. This is ok, because the service is oblivious
32923     // to the needs patching flag before the chunk is released as complete.
ClearNeedsPatchingFlag()32924     void ClearNeedsPatchingFlag() {
32925       ChunkHeader* chunk_header = header();
32926       auto packets = chunk_header->packets.load(std::memory_order_relaxed);
32927       packets.flags &= ~ChunkHeader::kChunkNeedsPatching;
32928       chunk_header->packets.store(packets, std::memory_order_release);
32929     }
32930 
32931    private:
32932     friend class SharedMemoryABI;
32933     Chunk(uint8_t* begin, uint16_t size, uint8_t chunk_idx);
32934 
32935     // Don't add extra fields, keep the move operator fast.
32936     uint8_t* begin_ = nullptr;
32937     uint16_t size_ = 0;
32938     uint8_t chunk_idx_ = 0;
32939   };
32940 
32941   // Construct an instance from an existing shared memory buffer.
32942   SharedMemoryABI(uint8_t* start, size_t size, size_t page_size);
32943   SharedMemoryABI();
32944 
32945   void Initialize(uint8_t* start, size_t size, size_t page_size);
32946 
start() const32947   uint8_t* start() const { return start_; }
end() const32948   uint8_t* end() const { return start_ + size_; }
size() const32949   size_t size() const { return size_; }
page_size() const32950   size_t page_size() const { return page_size_; }
num_pages() const32951   size_t num_pages() const { return num_pages_; }
is_valid()32952   bool is_valid() { return num_pages() > 0; }
32953 
page_start(size_t page_idx)32954   uint8_t* page_start(size_t page_idx) {
32955     PERFETTO_DCHECK(page_idx < num_pages_);
32956     return start_ + page_size_ * page_idx;
32957   }
32958 
page_header(size_t page_idx)32959   PageHeader* page_header(size_t page_idx) {
32960     return reinterpret_cast<PageHeader*>(page_start(page_idx));
32961   }
32962 
32963   // Returns true if the page is fully clear and has not been partitioned yet.
32964   // The state of the page can change at any point after this returns (or even
32965   // before). The Producer should use this only as a hint to decide out whether
32966   // it should TryPartitionPage() or acquire an individual chunk.
is_page_free(size_t page_idx)32967   bool is_page_free(size_t page_idx) {
32968     return page_header(page_idx)->layout.load(std::memory_order_relaxed) == 0;
32969   }
32970 
32971   // Returns true if all chunks in the page are kChunkComplete. As above, this
32972   // is advisory only. The Service is supposed to use this only to decide
32973   // whether to TryAcquireAllChunksForReading() or not.
is_page_complete(size_t page_idx)32974   bool is_page_complete(size_t page_idx) {
32975     auto layout = page_header(page_idx)->layout.load(std::memory_order_relaxed);
32976     const uint32_t num_chunks = GetNumChunksForLayout(layout);
32977     if (num_chunks == 0)
32978       return false;  // Non partitioned pages cannot be complete.
32979     return (layout & kAllChunksMask) ==
32980            (kAllChunksComplete & ((1 << (num_chunks * kChunkShift)) - 1));
32981   }
32982 
32983   // For testing / debugging only.
page_header_dbg(size_t page_idx)32984   std::string page_header_dbg(size_t page_idx) {
32985     uint32_t x = page_header(page_idx)->layout.load(std::memory_order_relaxed);
32986     return std::bitset<32>(x).to_string();
32987   }
32988 
32989   // Returns the page layout, which is a bitmap that specifies the chunking
32990   // layout of the page and each chunk's current state. Reads with an
32991   // acquire-load semantic to ensure a producer's writes corresponding to an
32992   // update of the layout (e.g. clearing a chunk's header) are observed
32993   // consistently.
GetPageLayout(size_t page_idx)32994   uint32_t GetPageLayout(size_t page_idx) {
32995     return page_header(page_idx)->layout.load(std::memory_order_acquire);
32996   }
32997 
32998   // Returns a bitmap in which each bit is set if the corresponding Chunk exists
32999   // in the page (according to the page layout) and is free. If the page is not
33000   // partitioned it returns 0 (as if the page had no free chunks).
33001   uint32_t GetFreeChunks(size_t page_idx);
33002 
33003   // Tries to atomically partition a page with the given |layout|. Returns true
33004   // if the page was free and has been partitioned with the given |layout|,
33005   // false if the page wasn't free anymore by the time we got there.
33006   // If succeeds all the chunks are atomically set in the kChunkFree state.
33007   bool TryPartitionPage(size_t page_idx, PageLayout layout);
33008 
33009   // Tries to atomically mark a single chunk within the page as
33010   // kChunkBeingWritten. Returns an invalid chunk if the page is not partitioned
33011   // or the chunk is not in the kChunkFree state. If succeeds sets the chunk
33012   // header to |header|.
TryAcquireChunkForWriting(size_t page_idx,size_t chunk_idx,const ChunkHeader * header)33013   Chunk TryAcquireChunkForWriting(size_t page_idx,
33014                                   size_t chunk_idx,
33015                                   const ChunkHeader* header) {
33016     return TryAcquireChunk(page_idx, chunk_idx, kChunkBeingWritten, header);
33017   }
33018 
33019   // Similar to TryAcquireChunkForWriting. Fails if the chunk isn't in the
33020   // kChunkComplete state.
TryAcquireChunkForReading(size_t page_idx,size_t chunk_idx)33021   Chunk TryAcquireChunkForReading(size_t page_idx, size_t chunk_idx) {
33022     return TryAcquireChunk(page_idx, chunk_idx, kChunkBeingRead, nullptr);
33023   }
33024 
33025   // The caller must have successfully TryAcquireAllChunksForReading() or it
33026   // needs to guarantee that the chunk is already in the kChunkBeingWritten
33027   // state.
33028   Chunk GetChunkUnchecked(size_t page_idx,
33029                           uint32_t page_layout,
33030                           size_t chunk_idx);
33031 
33032   // Puts a chunk into the kChunkComplete state. Returns the page index.
ReleaseChunkAsComplete(Chunk chunk)33033   size_t ReleaseChunkAsComplete(Chunk chunk) {
33034     return ReleaseChunk(std::move(chunk), kChunkComplete);
33035   }
33036 
33037   // Puts a chunk into the kChunkFree state. Returns the page index.
ReleaseChunkAsFree(Chunk chunk)33038   size_t ReleaseChunkAsFree(Chunk chunk) {
33039     return ReleaseChunk(std::move(chunk), kChunkFree);
33040   }
33041 
GetChunkState(size_t page_idx,size_t chunk_idx)33042   ChunkState GetChunkState(size_t page_idx, size_t chunk_idx) {
33043     PageHeader* phdr = page_header(page_idx);
33044     uint32_t layout = phdr->layout.load(std::memory_order_relaxed);
33045     return GetChunkStateFromLayout(layout, chunk_idx);
33046   }
33047 
33048   std::pair<size_t, size_t> GetPageAndChunkIndex(const Chunk& chunk);
33049 
GetChunkSizeForLayout(uint32_t page_layout) const33050   uint16_t GetChunkSizeForLayout(uint32_t page_layout) const {
33051     return chunk_sizes_[(page_layout & kLayoutMask) >> kLayoutShift];
33052   }
33053 
GetChunkStateFromLayout(uint32_t page_layout,size_t chunk_idx)33054   static ChunkState GetChunkStateFromLayout(uint32_t page_layout,
33055                                             size_t chunk_idx) {
33056     return static_cast<ChunkState>((page_layout >> (chunk_idx * kChunkShift)) &
33057                                    kChunkMask);
33058   }
33059 
GetNumChunksForLayout(uint32_t page_layout)33060   static constexpr uint32_t GetNumChunksForLayout(uint32_t page_layout) {
33061     return kNumChunksForLayout[(page_layout & kLayoutMask) >> kLayoutShift];
33062   }
33063 
33064   // Returns a bitmap in which each bit is set if the corresponding Chunk exists
33065   // in the page (according to the page layout) and is not free. If the page is
33066   // not partitioned it returns 0 (as if the page had no used chunks). Bit N
33067   // corresponds to Chunk N.
GetUsedChunks(uint32_t page_layout)33068   static uint32_t GetUsedChunks(uint32_t page_layout) {
33069     const uint32_t num_chunks = GetNumChunksForLayout(page_layout);
33070     uint32_t res = 0;
33071     for (uint32_t i = 0; i < num_chunks; i++) {
33072       res |= ((page_layout & kChunkMask) != kChunkFree) ? (1 << i) : 0;
33073       page_layout >>= kChunkShift;
33074     }
33075     return res;
33076   }
33077 
33078  private:
33079   SharedMemoryABI(const SharedMemoryABI&) = delete;
33080   SharedMemoryABI& operator=(const SharedMemoryABI&) = delete;
33081 
33082   Chunk TryAcquireChunk(size_t page_idx,
33083                         size_t chunk_idx,
33084                         ChunkState,
33085                         const ChunkHeader*);
33086   size_t ReleaseChunk(Chunk chunk, ChunkState);
33087 
33088   uint8_t* start_ = nullptr;
33089   size_t size_ = 0;
33090   size_t page_size_ = 0;
33091   size_t num_pages_ = 0;
33092   std::array<uint16_t, kNumPageLayouts> chunk_sizes_;
33093 };
33094 
33095 }  // namespace perfetto
33096 
33097 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ABI_H_
33098 /*
33099  * Copyright (C) 2017 The Android Open Source Project
33100  *
33101  * Licensed under the Apache License, Version 2.0 (the "License");
33102  * you may not use this file except in compliance with the
33103  * License. You may obtain a copy of the License at
33104  *
33105  *      http://www.apache.org/licenses/LICENSE-2.0
33106  *
33107  * Unless required by applicable law or agreed to in writing,
33108  * software distributed under the License is distributed on an "AS
33109  * IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
33110  * express or implied. See the License for the specific language
33111  * governing permissions and limitations under the License.
33112  */
33113 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
33114 
33115 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
33116 // gen_amalgamated expanded: #include "perfetto/base/time.h"
33117 
33118 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
33119 #include <sys/mman.h>
33120 #endif
33121 
33122 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
33123 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
33124 
33125 namespace perfetto {
33126 
33127 namespace {
33128 
33129 constexpr int kRetryAttempts = 64;
33130 
WaitBeforeNextAttempt(int attempt)33131 inline void WaitBeforeNextAttempt(int attempt) {
33132   if (attempt < kRetryAttempts / 2) {
33133     std::this_thread::yield();
33134   } else {
33135     base::SleepMicroseconds((unsigned(attempt) / 10) * 1000);
33136   }
33137 }
33138 
33139 // Returns the largest 4-bytes aligned chunk size <= |page_size| / |divider|
33140 // for each divider in PageLayout.
GetChunkSize(size_t page_size,size_t divider)33141 constexpr size_t GetChunkSize(size_t page_size, size_t divider) {
33142   return ((page_size - sizeof(SharedMemoryABI::PageHeader)) / divider) & ~3UL;
33143 }
33144 
33145 // Initializer for the const |chunk_sizes_| array.
InitChunkSizes(size_t page_size)33146 std::array<uint16_t, SharedMemoryABI::kNumPageLayouts> InitChunkSizes(
33147     size_t page_size) {
33148   static_assert(SharedMemoryABI::kNumPageLayouts ==
33149                     base::ArraySize(SharedMemoryABI::kNumChunksForLayout),
33150                 "kNumPageLayouts out of date");
33151   std::array<uint16_t, SharedMemoryABI::kNumPageLayouts> res = {};
33152   for (size_t i = 0; i < SharedMemoryABI::kNumPageLayouts; i++) {
33153     size_t num_chunks = SharedMemoryABI::kNumChunksForLayout[i];
33154     size_t size = num_chunks == 0 ? 0 : GetChunkSize(page_size, num_chunks);
33155     PERFETTO_CHECK(size <= std::numeric_limits<uint16_t>::max());
33156     res[i] = static_cast<uint16_t>(size);
33157   }
33158   return res;
33159 }
33160 
ClearChunkHeader(SharedMemoryABI::ChunkHeader * header)33161 inline void ClearChunkHeader(SharedMemoryABI::ChunkHeader* header) {
33162   header->writer_id.store(0u, std::memory_order_relaxed);
33163   header->chunk_id.store(0u, std::memory_order_relaxed);
33164   header->packets.store({}, std::memory_order_release);
33165 }
33166 
33167 }  // namespace
33168 
33169 // static
33170 constexpr uint32_t SharedMemoryABI::kNumChunksForLayout[];
33171 constexpr const char* SharedMemoryABI::kChunkStateStr[];
33172 constexpr const size_t SharedMemoryABI::kInvalidPageIdx;
33173 constexpr const size_t SharedMemoryABI::kMinPageSize;
33174 constexpr const size_t SharedMemoryABI::kMaxPageSize;
33175 constexpr const size_t SharedMemoryABI::kPacketSizeDropPacket;
33176 
33177 SharedMemoryABI::SharedMemoryABI() = default;
33178 
SharedMemoryABI(uint8_t * start,size_t size,size_t page_size)33179 SharedMemoryABI::SharedMemoryABI(uint8_t* start,
33180                                  size_t size,
33181                                  size_t page_size) {
33182   Initialize(start, size, page_size);
33183 }
33184 
Initialize(uint8_t * start,size_t size,size_t page_size)33185 void SharedMemoryABI::Initialize(uint8_t* start,
33186                                  size_t size,
33187                                  size_t page_size) {
33188   start_ = start;
33189   size_ = size;
33190   page_size_ = page_size;
33191   num_pages_ = size / page_size;
33192   chunk_sizes_ = InitChunkSizes(page_size);
33193   static_assert(sizeof(PageHeader) == 8, "PageHeader size");
33194   static_assert(sizeof(ChunkHeader) == 8, "ChunkHeader size");
33195   static_assert(sizeof(ChunkHeader::chunk_id) == sizeof(ChunkID),
33196                 "ChunkID size");
33197 
33198   static_assert(sizeof(ChunkHeader::Packets) == 2, "ChunkHeader::Packets size");
33199   static_assert(alignof(ChunkHeader) == kChunkAlignment,
33200                 "ChunkHeader alignment");
33201 
33202   // In theory std::atomic does not guarantee that the underlying type
33203   // consists only of the actual atomic word. Theoretically it could have
33204   // locks or other state. In practice most implementations just implement
33205   // them without extra state. The code below overlays the atomic into the
33206   // SMB, hence relies on this implementation detail. This should be fine
33207   // pragmatically (Chrome's base makes the same assumption), but let's have a
33208   // check for this.
33209   static_assert(sizeof(std::atomic<uint32_t>) == sizeof(uint32_t) &&
33210                     sizeof(std::atomic<uint16_t>) == sizeof(uint16_t),
33211                 "Incompatible STL <atomic> implementation");
33212 
33213   // Chec that the kAllChunks(Complete,Free) are consistent with the
33214   // ChunkState enum values.
33215 
33216   // These must be zero because rely on zero-initialized memory being
33217   // interpreted as "free".
33218   static_assert(kChunkFree == 0 && kAllChunksFree == 0,
33219                 "kChunkFree/kAllChunksFree and must be 0");
33220 
33221   static_assert((kAllChunksComplete & kChunkMask) == kChunkComplete,
33222                 "kAllChunksComplete out of sync with kChunkComplete");
33223 
33224   // Check the consistency of the kMax... constants.
33225   static_assert(sizeof(ChunkHeader::writer_id) == sizeof(WriterID),
33226                 "WriterID size");
33227   ChunkHeader chunk_header{};
33228   chunk_header.chunk_id.store(static_cast<uint32_t>(-1));
33229   PERFETTO_CHECK(chunk_header.chunk_id.load() == kMaxChunkID);
33230 
33231   chunk_header.writer_id.store(static_cast<uint16_t>(-1));
33232   PERFETTO_CHECK(kMaxWriterID <= chunk_header.writer_id.load());
33233 
33234   PERFETTO_CHECK(page_size >= kMinPageSize);
33235   PERFETTO_CHECK(page_size <= kMaxPageSize);
33236   PERFETTO_CHECK(page_size % kMinPageSize == 0);
33237   PERFETTO_CHECK(reinterpret_cast<uintptr_t>(start) % kMinPageSize == 0);
33238   PERFETTO_CHECK(size % page_size == 0);
33239 }
33240 
GetChunkUnchecked(size_t page_idx,uint32_t page_layout,size_t chunk_idx)33241 SharedMemoryABI::Chunk SharedMemoryABI::GetChunkUnchecked(size_t page_idx,
33242                                                           uint32_t page_layout,
33243                                                           size_t chunk_idx) {
33244   const size_t num_chunks = GetNumChunksForLayout(page_layout);
33245   PERFETTO_DCHECK(chunk_idx < num_chunks);
33246   // Compute the chunk virtual address and write it into |chunk|.
33247   const uint16_t chunk_size = GetChunkSizeForLayout(page_layout);
33248   size_t chunk_offset_in_page = sizeof(PageHeader) + chunk_idx * chunk_size;
33249 
33250   Chunk chunk(page_start(page_idx) + chunk_offset_in_page, chunk_size,
33251               static_cast<uint8_t>(chunk_idx));
33252   PERFETTO_DCHECK(chunk.end() <= end());
33253   return chunk;
33254 }
33255 
TryAcquireChunk(size_t page_idx,size_t chunk_idx,ChunkState desired_chunk_state,const ChunkHeader * header)33256 SharedMemoryABI::Chunk SharedMemoryABI::TryAcquireChunk(
33257     size_t page_idx,
33258     size_t chunk_idx,
33259     ChunkState desired_chunk_state,
33260     const ChunkHeader* header) {
33261   PERFETTO_DCHECK(desired_chunk_state == kChunkBeingRead ||
33262                   desired_chunk_state == kChunkBeingWritten);
33263   PageHeader* phdr = page_header(page_idx);
33264   for (int attempt = 0; attempt < kRetryAttempts; attempt++) {
33265     uint32_t layout = phdr->layout.load(std::memory_order_acquire);
33266     const size_t num_chunks = GetNumChunksForLayout(layout);
33267 
33268     // The page layout has changed (or the page is free).
33269     if (chunk_idx >= num_chunks)
33270       return Chunk();
33271 
33272     // Verify that the chunk is still in a state that allows the transition to
33273     // |desired_chunk_state|. The only allowed transitions are:
33274     // 1. kChunkFree -> kChunkBeingWritten (Producer).
33275     // 2. kChunkComplete -> kChunkBeingRead (Service).
33276     ChunkState expected_chunk_state =
33277         desired_chunk_state == kChunkBeingWritten ? kChunkFree : kChunkComplete;
33278     auto cur_chunk_state = (layout >> (chunk_idx * kChunkShift)) & kChunkMask;
33279     if (cur_chunk_state != expected_chunk_state)
33280       return Chunk();
33281 
33282     uint32_t next_layout = layout;
33283     next_layout &= ~(kChunkMask << (chunk_idx * kChunkShift));
33284     next_layout |= (desired_chunk_state << (chunk_idx * kChunkShift));
33285     if (phdr->layout.compare_exchange_strong(layout, next_layout,
33286                                              std::memory_order_acq_rel)) {
33287       // Compute the chunk virtual address and write it into |chunk|.
33288       Chunk chunk = GetChunkUnchecked(page_idx, layout, chunk_idx);
33289       if (desired_chunk_state == kChunkBeingWritten) {
33290         PERFETTO_DCHECK(header);
33291         ChunkHeader* new_header = chunk.header();
33292         new_header->writer_id.store(header->writer_id,
33293                                     std::memory_order_relaxed);
33294         new_header->chunk_id.store(header->chunk_id, std::memory_order_relaxed);
33295         new_header->packets.store(header->packets, std::memory_order_release);
33296       }
33297       return chunk;
33298     }
33299     WaitBeforeNextAttempt(attempt);
33300   }
33301   return Chunk();  // All our attempts failed.
33302 }
33303 
TryPartitionPage(size_t page_idx,PageLayout layout)33304 bool SharedMemoryABI::TryPartitionPage(size_t page_idx, PageLayout layout) {
33305   PERFETTO_DCHECK(layout >= kPageDiv1 && layout <= kPageDiv14);
33306   uint32_t expected_layout = 0;  // Free page.
33307   uint32_t next_layout = (layout << kLayoutShift) & kLayoutMask;
33308   PageHeader* phdr = page_header(page_idx);
33309   if (!phdr->layout.compare_exchange_strong(expected_layout, next_layout,
33310                                             std::memory_order_acq_rel)) {
33311     return false;
33312   }
33313   return true;
33314 }
33315 
GetFreeChunks(size_t page_idx)33316 uint32_t SharedMemoryABI::GetFreeChunks(size_t page_idx) {
33317   uint32_t layout =
33318       page_header(page_idx)->layout.load(std::memory_order_relaxed);
33319   const uint32_t num_chunks = GetNumChunksForLayout(layout);
33320   uint32_t res = 0;
33321   for (uint32_t i = 0; i < num_chunks; i++) {
33322     res |= ((layout & kChunkMask) == kChunkFree) ? (1 << i) : 0;
33323     layout >>= kChunkShift;
33324   }
33325   return res;
33326 }
33327 
ReleaseChunk(Chunk chunk,ChunkState desired_chunk_state)33328 size_t SharedMemoryABI::ReleaseChunk(Chunk chunk,
33329                                      ChunkState desired_chunk_state) {
33330   PERFETTO_DCHECK(desired_chunk_state == kChunkComplete ||
33331                   desired_chunk_state == kChunkFree);
33332 
33333   size_t page_idx;
33334   size_t chunk_idx;
33335   std::tie(page_idx, chunk_idx) = GetPageAndChunkIndex(chunk);
33336 
33337   // Reset header fields, so that the service can identify when the chunk's
33338   // header has been initialized by the producer.
33339   if (desired_chunk_state == kChunkFree)
33340     ClearChunkHeader(chunk.header());
33341 
33342   for (int attempt = 0; attempt < kRetryAttempts; attempt++) {
33343     PageHeader* phdr = page_header(page_idx);
33344     uint32_t layout = phdr->layout.load(std::memory_order_relaxed);
33345     const size_t page_chunk_size = GetChunkSizeForLayout(layout);
33346 
33347     // TODO(primiano): this should not be a CHECK, because a malicious producer
33348     // could crash us by putting the chunk in an invalid state. This should
33349     // gracefully fail. Keep a CHECK until then.
33350     PERFETTO_CHECK(chunk.size() == page_chunk_size);
33351     const uint32_t chunk_state =
33352         ((layout >> (chunk_idx * kChunkShift)) & kChunkMask);
33353 
33354     // Verify that the chunk is still in a state that allows the transition to
33355     // |desired_chunk_state|. The only allowed transitions are:
33356     // 1. kChunkBeingWritten -> kChunkComplete (Producer).
33357     // 2. kChunkBeingRead -> kChunkFree (Service).
33358     ChunkState expected_chunk_state;
33359     if (desired_chunk_state == kChunkComplete) {
33360       expected_chunk_state = kChunkBeingWritten;
33361     } else {
33362       expected_chunk_state = kChunkBeingRead;
33363     }
33364 
33365     // TODO(primiano): should not be a CHECK (same rationale of comment above).
33366     PERFETTO_CHECK(chunk_state == expected_chunk_state);
33367     uint32_t next_layout = layout;
33368     next_layout &= ~(kChunkMask << (chunk_idx * kChunkShift));
33369     next_layout |= (desired_chunk_state << (chunk_idx * kChunkShift));
33370 
33371     // If we are freeing a chunk and all the other chunks in the page are free
33372     // we should de-partition the page and mark it as clear.
33373     if ((next_layout & kAllChunksMask) == kAllChunksFree)
33374       next_layout = 0;
33375 
33376     if (phdr->layout.compare_exchange_strong(layout, next_layout,
33377                                              std::memory_order_acq_rel)) {
33378       return page_idx;
33379     }
33380     WaitBeforeNextAttempt(attempt);
33381   }
33382   // Too much contention on this page. Give up. This page will be left pending
33383   // forever but there isn't much more we can do at this point.
33384   PERFETTO_DFATAL("Too much contention on page.");
33385   return kInvalidPageIdx;
33386 }
33387 
33388 SharedMemoryABI::Chunk::Chunk() = default;
33389 
Chunk(uint8_t * begin,uint16_t size,uint8_t chunk_idx)33390 SharedMemoryABI::Chunk::Chunk(uint8_t* begin, uint16_t size, uint8_t chunk_idx)
33391     : begin_(begin), size_(size), chunk_idx_(chunk_idx) {
33392   PERFETTO_CHECK(reinterpret_cast<uintptr_t>(begin) % kChunkAlignment == 0);
33393   PERFETTO_CHECK(size > 0);
33394 }
33395 
Chunk(Chunk && o)33396 SharedMemoryABI::Chunk::Chunk(Chunk&& o) noexcept {
33397   *this = std::move(o);
33398 }
33399 
operator =(Chunk && o)33400 SharedMemoryABI::Chunk& SharedMemoryABI::Chunk::operator=(Chunk&& o) {
33401   begin_ = o.begin_;
33402   size_ = o.size_;
33403   chunk_idx_ = o.chunk_idx_;
33404   o.begin_ = nullptr;
33405   o.size_ = 0;
33406   o.chunk_idx_ = 0;
33407   return *this;
33408 }
33409 
GetPageAndChunkIndex(const Chunk & chunk)33410 std::pair<size_t, size_t> SharedMemoryABI::GetPageAndChunkIndex(
33411     const Chunk& chunk) {
33412   PERFETTO_DCHECK(chunk.is_valid());
33413   PERFETTO_DCHECK(chunk.begin() >= start_);
33414   PERFETTO_DCHECK(chunk.end() <= start_ + size_);
33415 
33416   // TODO(primiano): The divisions below could be avoided if we cached
33417   // |page_shift_|.
33418   const uintptr_t rel_addr = static_cast<uintptr_t>(chunk.begin() - start_);
33419   const size_t page_idx = rel_addr / page_size_;
33420   const size_t offset = rel_addr % page_size_;
33421   PERFETTO_DCHECK(offset >= sizeof(PageHeader));
33422   PERFETTO_DCHECK(offset % kChunkAlignment == 0);
33423   PERFETTO_DCHECK((offset - sizeof(PageHeader)) % chunk.size() == 0);
33424   const size_t chunk_idx = (offset - sizeof(PageHeader)) / chunk.size();
33425   PERFETTO_DCHECK(chunk_idx < kMaxChunksPerPage);
33426   PERFETTO_DCHECK(chunk_idx < GetNumChunksForLayout(GetPageLayout(page_idx)));
33427   return std::make_pair(page_idx, chunk_idx);
33428 }
33429 
33430 }  // namespace perfetto
33431 // gen_amalgamated begin source: src/tracing/core/shared_memory_arbiter_impl.cc
33432 // gen_amalgamated begin header: src/tracing/core/shared_memory_arbiter_impl.h
33433 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/shared_memory_arbiter.h
33434 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/tracing_service.h
33435 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/shared_memory.h
33436 /*
33437  * Copyright (C) 2017 The Android Open Source Project
33438  *
33439  * Licensed under the Apache License, Version 2.0 (the "License");
33440  * you may not use this file except in compliance with the License.
33441  * You may obtain a copy of the License at
33442  *
33443  *      http://www.apache.org/licenses/LICENSE-2.0
33444  *
33445  * Unless required by applicable law or agreed to in writing, software
33446  * distributed under the License is distributed on an "AS IS" BASIS,
33447  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
33448  * See the License for the specific language governing permissions and
33449  * limitations under the License.
33450  */
33451 
33452 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_H_
33453 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_H_
33454 
33455 #include <stddef.h>
33456 
33457 #include <memory>
33458 
33459 // gen_amalgamated expanded: #include "perfetto/base/export.h"
33460 // gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
33461 
33462 namespace perfetto {
33463 
33464 // An abstract interface that models the shared memory region shared between
33465 // Service and Producer. The concrete implementation of this is up to the
33466 // transport layer. This can be as simple as a malloc()-ed buffer, if both
33467 // Producer and Service are hosted in the same process, or some posix shared
33468 // memory for the out-of-process case (see src/unix_rpc).
33469 // Both this class and the Factory are subclassed by the transport layer, which
33470 // will attach platform specific fields to it (e.g., a unix file descriptor).
33471 class PERFETTO_EXPORT SharedMemory {
33472  public:
33473   class PERFETTO_EXPORT Factory {
33474    public:
33475     virtual ~Factory();
33476     virtual std::unique_ptr<SharedMemory> CreateSharedMemory(size_t) = 0;
33477   };
33478 
33479   // The transport layer is expected to tear down the resource associated to
33480   // this object region when destroyed.
33481   virtual ~SharedMemory();
33482 
33483   virtual void* start() const = 0;
33484   virtual size_t size() const = 0;
33485 };
33486 
33487 }  // namespace perfetto
33488 
33489 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_H_
33490 /*
33491  * Copyright (C) 2017 The Android Open Source Project
33492  *
33493  * Licensed under the Apache License, Version 2.0 (the "License");
33494  * you may not use this file except in compliance with the License.
33495  * You may obtain a copy of the License at
33496  *
33497  *      http://www.apache.org/licenses/LICENSE-2.0
33498  *
33499  * Unless required by applicable law or agreed to in writing, software
33500  * distributed under the License is distributed on an "AS IS" BASIS,
33501  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
33502  * See the License for the specific language governing permissions and
33503  * limitations under the License.
33504  */
33505 
33506 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACING_SERVICE_H_
33507 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACING_SERVICE_H_
33508 
33509 #include <stdint.h>
33510 
33511 #include <functional>
33512 #include <memory>
33513 #include <vector>
33514 
33515 // gen_amalgamated expanded: #include "perfetto/base/export.h"
33516 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
33517 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
33518 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
33519 // gen_amalgamated expanded: #include "perfetto/tracing/buffer_exhausted_policy.h"
33520 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
33521 
33522 namespace perfetto {
33523 
33524 namespace base {
33525 class TaskRunner;
33526 }  // namespace base
33527 
33528 class Consumer;
33529 class Producer;
33530 class SharedMemoryArbiter;
33531 class TraceWriter;
33532 
33533 // Exposed for testing.
33534 std::string GetBugreportPath();
33535 
33536 // TODO: for the moment this assumes that all the calls happen on the same
33537 // thread/sequence. Not sure this will be the case long term in Chrome.
33538 
33539 // The API for the Producer port of the Service.
33540 // Subclassed by:
33541 // 1. The tracing_service_impl.cc business logic when returning it in response
33542 //    to the ConnectProducer() method.
33543 // 2. The transport layer (e.g., src/ipc) when the producer and
33544 //    the service don't talk locally but via some IPC mechanism.
33545 class PERFETTO_EXPORT ProducerEndpoint {
33546  public:
33547   virtual ~ProducerEndpoint();
33548 
33549   // Called by the Producer to (un)register data sources. Data sources are
33550   // identified by their name (i.e. DataSourceDescriptor.name)
33551   virtual void RegisterDataSource(const DataSourceDescriptor&) = 0;
33552   virtual void UnregisterDataSource(const std::string& name) = 0;
33553 
33554   // Associate the trace writer with the given |writer_id| with
33555   // |target_buffer|. The service may use this information to retrieve and
33556   // copy uncommitted chunks written by the trace writer into its associated
33557   // buffer, e.g. when a producer process crashes or when a flush is
33558   // necessary.
33559   virtual void RegisterTraceWriter(uint32_t writer_id,
33560                                    uint32_t target_buffer) = 0;
33561 
33562   // Remove the association of the trace writer previously created via
33563   // RegisterTraceWriter.
33564   virtual void UnregisterTraceWriter(uint32_t writer_id) = 0;
33565 
33566   // Called by the Producer to signal that some pages in the shared memory
33567   // buffer (shared between Service and Producer) have changed.
33568   // When the Producer and the Service are hosted in the same process and
33569   // hence potentially live on the same task runner, This method must call
33570   // TracingServiceImpl's CommitData synchronously, without any PostTask()s,
33571   // if on the same thread. This is to avoid a deadlock where the Producer
33572   // exhausts its SMB and stalls waiting for the service to catch up with
33573   // reads, but the Service never gets to that because it lives on the same
33574   // thread.
33575   using CommitDataCallback = std::function<void()>;
33576   virtual void CommitData(const CommitDataRequest&,
33577                           CommitDataCallback callback = {}) = 0;
33578 
33579   virtual SharedMemory* shared_memory() const = 0;
33580 
33581   // Size of shared memory buffer pages. It's always a multiple of 4K.
33582   // See shared_memory_abi.h
33583   virtual size_t shared_buffer_page_size_kb() const = 0;
33584 
33585   // Creates a trace writer, which allows to create events, handling the
33586   // underying shared memory buffer and signalling to the Service. This method
33587   // is thread-safe but the returned object is not. A TraceWriter should be
33588   // used only from a single thread, or the caller has to handle sequencing
33589   // via a mutex or equivalent. This method can only be called if
33590   // TracingService::ConnectProducer was called with |in_process=true|.
33591   // Args:
33592   // |target_buffer| is the target buffer ID where the data produced by the
33593   // writer should be stored by the tracing service. This value is passed
33594   // upon creation of the data source (StartDataSource()) in the
33595   // DataSourceConfig.target_buffer().
33596   virtual std::unique_ptr<TraceWriter> CreateTraceWriter(
33597       BufferID target_buffer,
33598       BufferExhaustedPolicy buffer_exhausted_policy =
33599           BufferExhaustedPolicy::kDefault) = 0;
33600 
33601   // TODO(eseckler): Also expose CreateStartupTraceWriter() ?
33602 
33603   // In some cases you can access the producer's SharedMemoryArbiter (for
33604   // example if TracingService::ConnectProducer is called with
33605   // |in_process=true|). The SharedMemoryArbiter can be used to create
33606   // TraceWriters which is able to directly commit chunks. For the
33607   // |in_process=true| case this can be done without going through an IPC layer.
33608   virtual SharedMemoryArbiter* MaybeSharedMemoryArbiter() = 0;
33609 
33610   // Whether the service accepted a shared memory buffer provided by the
33611   // producer.
33612   virtual bool IsShmemProvidedByProducer() const = 0;
33613 
33614   // Called in response to a Producer::Flush(request_id) call after all data
33615   // for the flush request has been committed.
33616   virtual void NotifyFlushComplete(FlushRequestID) = 0;
33617 
33618   // Called in response to one or more Producer::StartDataSource(),
33619   // if the data source registered setting the flag
33620   // DataSourceDescriptor.will_notify_on_start.
33621   virtual void NotifyDataSourceStarted(DataSourceInstanceID) = 0;
33622 
33623   // Called in response to one or more Producer::StopDataSource(),
33624   // if the data source registered setting the flag
33625   // DataSourceDescriptor.will_notify_on_stop.
33626   virtual void NotifyDataSourceStopped(DataSourceInstanceID) = 0;
33627 
33628   // This informs the service to activate any of these triggers if any tracing
33629   // session was waiting for them.
33630   virtual void ActivateTriggers(const std::vector<std::string>&) = 0;
33631 
33632   // Emits a synchronization barrier to linearize with the service. When
33633   // |callback| is invoked, the caller has the guarantee that the service has
33634   // seen and processed all the requests sent by this producer prior to the
33635   // Sync() call. Used mainly in tests.
33636   virtual void Sync(std::function<void()> callback) = 0;
33637 };  // class ProducerEndpoint.
33638 
33639 // The API for the Consumer port of the Service.
33640 // Subclassed by:
33641 // 1. The tracing_service_impl.cc business logic when returning it in response
33642 // to
33643 //    the ConnectConsumer() method.
33644 // 2. The transport layer (e.g., src/ipc) when the consumer and
33645 //    the service don't talk locally but via some IPC mechanism.
33646 class PERFETTO_EXPORT ConsumerEndpoint {
33647  public:
33648   virtual ~ConsumerEndpoint();
33649 
33650   // Enables tracing with the given TraceConfig. The ScopedFile argument is
33651   // used only when TraceConfig.write_into_file == true.
33652   // If TraceConfig.deferred_start == true data sources are configured via
33653   // SetupDataSource() but are not started until StartTracing() is called.
33654   // This is to support pre-initialization and fast triggering of traces.
33655   // The ScopedFile argument is used only when TraceConfig.write_into_file
33656   // == true.
33657   virtual void EnableTracing(const TraceConfig&,
33658                              base::ScopedFile = base::ScopedFile()) = 0;
33659 
33660   // Update the trace config of an existing tracing session; only a subset
33661   // of options can be changed mid-session. Currently the only
33662   // supported functionality is expanding the list of producer_name_filters()
33663   // (or removing the filter entirely) for existing data sources.
33664   virtual void ChangeTraceConfig(const TraceConfig&) = 0;
33665 
33666   // Starts all data sources configured in the trace config. This is used only
33667   // after calling EnableTracing() with TraceConfig.deferred_start=true.
33668   // It's a no-op if called after a regular EnableTracing(), without setting
33669   // deferred_start.
33670   virtual void StartTracing() = 0;
33671 
33672   virtual void DisableTracing() = 0;
33673 
33674   // Requests all data sources to flush their data immediately and invokes the
33675   // passed callback once all of them have acked the flush (in which case
33676   // the callback argument |success| will be true) or |timeout_ms| are elapsed
33677   // (in which case |success| will be false).
33678   // If |timeout_ms| is 0 the TraceConfig's flush_timeout_ms is used, or,
33679   // if that one is not set (or is set to 0), kDefaultFlushTimeoutMs (5s) is
33680   // used.
33681   using FlushCallback = std::function<void(bool /*success*/)>;
33682   virtual void Flush(uint32_t timeout_ms, FlushCallback) = 0;
33683 
33684   // Tracing data will be delivered invoking Consumer::OnTraceData().
33685   virtual void ReadBuffers() = 0;
33686 
33687   virtual void FreeBuffers() = 0;
33688 
33689   // Will call OnDetach().
33690   virtual void Detach(const std::string& key) = 0;
33691 
33692   // Will call OnAttach().
33693   virtual void Attach(const std::string& key) = 0;
33694 
33695   // Will call OnTraceStats().
33696   virtual void GetTraceStats() = 0;
33697 
33698   // Start or stop observing events of selected types. |events_mask| specifies
33699   // the types of events to observe in a bitmask of ObservableEvents::Type.
33700   // To disable observing, pass 0.
33701   // Will call OnObservableEvents() repeatedly whenever an event of an enabled
33702   // ObservableEventType occurs.
33703   // TODO(eseckler): Extend this to support producers & data sources.
33704   virtual void ObserveEvents(uint32_t events_mask) = 0;
33705 
33706   // Used to obtain the list of connected data sources and other info about
33707   // the tracing service.
33708   using QueryServiceStateCallback =
33709       std::function<void(bool success, const TracingServiceState&)>;
33710   virtual void QueryServiceState(QueryServiceStateCallback) = 0;
33711 
33712   // Used for feature detection. Makes sense only when the consumer and the
33713   // service talk over IPC and can be from different versions.
33714   using QueryCapabilitiesCallback =
33715       std::function<void(const TracingServiceCapabilities&)>;
33716   virtual void QueryCapabilities(QueryCapabilitiesCallback) = 0;
33717 
33718   // If any tracing session with TraceConfig.bugreport_score > 0 is running,
33719   // this will pick the highest-score one, stop it and save it into a fixed
33720   // path (See kBugreportTracePath).
33721   // The callback is invoked when the file has been saved, in case of success,
33722   // or whenever an error occurs.
33723   // Args:
33724   // - success: if true, an eligible trace was found and saved into file.
33725   //            If false, either there was no eligible trace running or
33726   //            something else failed (See |msg|).
33727   // - msg: human readable diagnostic messages to debug failures.
33728   using SaveTraceForBugreportCallback =
33729       std::function<void(bool /*success*/, const std::string& /*msg*/)>;
33730   virtual void SaveTraceForBugreport(SaveTraceForBugreportCallback) = 0;
33731 };  // class ConsumerEndpoint.
33732 
33733 // The public API of the tracing Service business logic.
33734 //
33735 // Exposed to:
33736 // 1. The transport layer (e.g., src/unix_rpc/unix_service_host.cc),
33737 //    which forwards commands received from a remote producer or consumer to
33738 //    the actual service implementation.
33739 // 2. Tests.
33740 //
33741 // Subclassed by:
33742 //   The service business logic in src/core/tracing_service_impl.cc.
33743 class PERFETTO_EXPORT TracingService {
33744  public:
33745   using ProducerEndpoint = perfetto::ProducerEndpoint;
33746   using ConsumerEndpoint = perfetto::ConsumerEndpoint;
33747 
33748   enum class ProducerSMBScrapingMode {
33749     // Use service's default setting for SMB scraping. Currently, the default
33750     // mode is to disable SMB scraping, but this may change in the future.
33751     kDefault,
33752 
33753     // Enable scraping of uncommitted chunks in producers' shared memory
33754     // buffers.
33755     kEnabled,
33756 
33757     // Disable scraping of uncommitted chunks in producers' shared memory
33758     // buffers.
33759     kDisabled
33760   };
33761 
33762   // Implemented in src/core/tracing_service_impl.cc .
33763   static std::unique_ptr<TracingService> CreateInstance(
33764       std::unique_ptr<SharedMemory::Factory>,
33765       base::TaskRunner*);
33766 
33767   virtual ~TracingService();
33768 
33769   // Connects a Producer instance and obtains a ProducerEndpoint, which is
33770   // essentially a 1:1 channel between one Producer and the Service.
33771   //
33772   // The caller has to guarantee that the passed Producer will be alive as long
33773   // as the returned ProducerEndpoint is alive. Both the passed Producer and the
33774   // returned ProducerEndpoint must live on the same task runner of the service,
33775   // specifically:
33776   // 1) The Service will call Producer::* methods on the Service's task runner.
33777   // 2) The Producer should call ProducerEndpoint::* methods only on the
33778   //    service's task runner, except for ProducerEndpoint::CreateTraceWriter(),
33779   //    which can be called on any thread. To disconnect just destroy the
33780   //    returned ProducerEndpoint object. It is safe to destroy the Producer
33781   //    once the Producer::OnDisconnect() has been invoked.
33782   //
33783   // |uid| is the trusted user id of the producer process, used by the consumers
33784   // for validating the origin of trace data. |shared_memory_size_hint_bytes|
33785   // and |shared_memory_page_size_hint_bytes| are optional hints on the size of
33786   // the shared memory buffer and its pages. The service can ignore the hints
33787   // (e.g., if the hints are unreasonably large or other sizes were configured
33788   // in a tracing session's config). |in_process| enables the ProducerEndpoint
33789   // to manage its own shared memory and enables use of
33790   // |ProducerEndpoint::CreateTraceWriter|.
33791   //
33792   // The producer can optionally provide a non-null |shm|, which the service
33793   // will adopt for the connection to the producer, provided it is correctly
33794   // sized. In this case, |shared_memory_page_size_hint_bytes| indicates the
33795   // page size used in this SMB. The producer can use this mechanism to record
33796   // tracing data to an SMB even before the tracing session is started by the
33797   // service. This is used in Chrome to implement startup tracing. If the buffer
33798   // is incorrectly sized, the service will discard the SMB and allocate a new
33799   // one, provided to the producer via ProducerEndpoint::shared_memory() after
33800   // OnTracingSetup(). To verify that the service accepted the SMB, the producer
33801   // may check via ProducerEndpoint::IsShmemProvidedByProducer(). If the service
33802   // accepted the SMB, the producer can then commit any data that is already in
33803   // the SMB after the tracing session was started by the service via
33804   // Producer::StartDataSource(). The |shm| will also be rejected when
33805   // connecting to a service that is too old (pre Android-11).
33806   //
33807   // Can return null in the unlikely event that service has too many producers
33808   // connected.
33809   virtual std::unique_ptr<ProducerEndpoint> ConnectProducer(
33810       Producer*,
33811       uid_t uid,
33812       const std::string& name,
33813       size_t shared_memory_size_hint_bytes = 0,
33814       bool in_process = false,
33815       ProducerSMBScrapingMode smb_scraping_mode =
33816           ProducerSMBScrapingMode::kDefault,
33817       size_t shared_memory_page_size_hint_bytes = 0,
33818       std::unique_ptr<SharedMemory> shm = nullptr,
33819       const std::string& sdk_version = {}) = 0;
33820 
33821   // Connects a Consumer instance and obtains a ConsumerEndpoint, which is
33822   // essentially a 1:1 channel between one Consumer and the Service.
33823   // The caller has to guarantee that the passed Consumer will be alive as long
33824   // as the returned ConsumerEndpoint is alive.
33825   // To disconnect just destroy the returned ConsumerEndpoint object. It is safe
33826   // to destroy the Consumer once the Consumer::OnDisconnect() has been invoked.
33827   virtual std::unique_ptr<ConsumerEndpoint> ConnectConsumer(Consumer*,
33828                                                             uid_t) = 0;
33829 
33830   // Enable/disable scraping of chunks in the shared memory buffer. If enabled,
33831   // the service will copy uncommitted but non-empty chunks from the SMB when
33832   // flushing (e.g. to handle unresponsive producers or producers unable to
33833   // flush their active chunks), on producer disconnect (e.g. to recover data
33834   // from crashed producers), and after disabling a tracing session (e.g. to
33835   // gather data from producers that didn't stop their data sources in time).
33836   //
33837   // This feature is currently used by Chrome.
33838   virtual void SetSMBScrapingEnabled(bool enabled) = 0;
33839 };
33840 
33841 }  // namespace perfetto
33842 
33843 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACING_SERVICE_H_
33844 /*
33845  * Copyright (C) 2018 The Android Open Source Project
33846  *
33847  * Licensed under the Apache License, Version 2.0 (the "License");
33848  * you may not use this file except in compliance with the License.
33849  * You may obtain a copy of the License at
33850  *
33851  *      http://www.apache.org/licenses/LICENSE-2.0
33852  *
33853  * Unless required by applicable law or agreed to in writing, software
33854  * distributed under the License is distributed on an "AS IS" BASIS,
33855  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
33856  * See the License for the specific language governing permissions and
33857  * limitations under the License.
33858  */
33859 
33860 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ARBITER_H_
33861 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ARBITER_H_
33862 
33863 #include <stddef.h>
33864 
33865 #include <functional>
33866 #include <memory>
33867 #include <vector>
33868 
33869 // gen_amalgamated expanded: #include "perfetto/base/export.h"
33870 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
33871 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
33872 // gen_amalgamated expanded: #include "perfetto/tracing/buffer_exhausted_policy.h"
33873 
33874 namespace perfetto {
33875 
33876 namespace base {
33877 class TaskRunner;
33878 }
33879 
33880 class SharedMemory;
33881 class TraceWriter;
33882 
33883 // Used by the Producer-side of the transport layer to vend TraceWriters
33884 // from the SharedMemory it receives from the Service-side.
33885 class PERFETTO_EXPORT SharedMemoryArbiter {
33886  public:
33887   virtual ~SharedMemoryArbiter();
33888 
33889   // Creates a new TraceWriter and assigns it a new WriterID. The WriterID is
33890   // written in each chunk header owned by a given TraceWriter and is used by
33891   // the Service to reconstruct TracePackets written by the same TraceWriter.
33892   // Returns null impl of TraceWriter if all WriterID slots are exhausted. The
33893   // writer will commit to the provided |target_buffer|. If the arbiter was
33894   // created via CreateUnbound(), only BufferExhaustedPolicy::kDrop is
33895   // supported.
33896   virtual std::unique_ptr<TraceWriter> CreateTraceWriter(
33897       BufferID target_buffer,
33898       BufferExhaustedPolicy buffer_exhausted_policy =
33899           BufferExhaustedPolicy::kDefault) = 0;
33900 
33901   // Creates a TraceWriter that will commit to the target buffer with the given
33902   // reservation ID (creating a new reservation for this ID if none exists yet).
33903   // The buffer reservation should be bound to an actual BufferID via
33904   // BindStartupTargetBuffer() once the actual BufferID is known. Only supported
33905   // if the arbiter was created using CreateUnbound(), and may be called while
33906   // the arbiter is unbound.
33907   //
33908   // While any unbound buffer reservation exists, all commits will be buffered
33909   // until all reservations were bound. Thus, until all reservations are bound,
33910   // the data written to the SMB will not be consumed by the service - the SMB
33911   // size should be chosen with this in mind. Startup writers always use
33912   // BufferExhaustedPolicy::kDrop, as we cannot feasibly stall while not
33913   // flushing to the service.
33914   //
33915   // The |target_buffer_reservation_id| should be greater than 0 but can
33916   // otherwise be freely chosen by the producer and is only used to translate
33917   // packets into the actual buffer id once
33918   // BindStartupTargetBuffer(reservation_id) is called. For example, Chrome uses
33919   // startup tracing not only for the first, but also subsequent tracing
33920   // sessions (to enable tracing in the browser process before it instructs the
33921   // tracing service to start tracing asynchronously, minimizing trace data loss
33922   // in the meantime), and increments the reservation ID between sessions.
33923   // Similarly, if more than a single target buffer per session is required
33924   // (e.g. for two different data sources), different reservation IDs should be
33925   // chosen for different targets buffers.
33926   virtual std::unique_ptr<TraceWriter> CreateStartupTraceWriter(
33927       uint16_t target_buffer_reservation_id) = 0;
33928 
33929   // Should only be called on unbound SharedMemoryArbiters. Binds the arbiter to
33930   // the provided ProducerEndpoint and TaskRunner. Should be called only once
33931   // and on the provided |TaskRunner|. Usually called by the producer (i.e., no
33932   // specific data source) once it connects to the service. Both the endpoint
33933   // and task runner should remain valid for the remainder of the arbiter's
33934   // lifetime.
33935   virtual void BindToProducerEndpoint(TracingService::ProducerEndpoint*,
33936                                       base::TaskRunner*) = 0;
33937 
33938   // Binds commits from TraceWriters created via CreateStartupTraceWriter() with
33939   // the given |target_buffer_reservation_id| to |target_buffer_id|. May only be
33940   // called once per |target_buffer_reservation_id|. Should be called on the
33941   // arbiter's TaskRunner, and after BindToProducerEndpoint() was called.
33942   // Usually, it is called by a specific data source, after it received its
33943   // configuration (including the target buffer ID) from the service.
33944   virtual void BindStartupTargetBuffer(uint16_t target_buffer_reservation_id,
33945                                        BufferID target_buffer_id) = 0;
33946 
33947   // Treat the reservation as resolved to an invalid buffer. Commits for this
33948   // reservation will be flushed to the service ASAP. The service will free
33949   // committed chunks but otherwise ignore them. The producer can call this
33950   // method, for example, if connection to the tracing service failed or the
33951   // session was stopped concurrently before the connection was established.
33952   virtual void AbortStartupTracingForReservation(
33953       uint16_t target_buffer_reservation_id) = 0;
33954 
33955   // Notifies the service that all data for the given FlushRequestID has been
33956   // committed in the shared memory buffer. Should only be called while bound.
33957   virtual void NotifyFlushComplete(FlushRequestID) = 0;
33958 
33959   // Sets the duration during which commits are batched. Args:
33960   // |batch_commits_duration_ms|: The length of the period, during which commits
33961   // by all trace writers are accumulated, before being sent to the service.
33962   // When the period ends, all accumulated commits are flushed. On the first
33963   // commit after the last flush, another delayed flush is scheduled to run in
33964   // |batch_commits_duration_ms|. If an immediate flush occurs (via
33965   // FlushPendingCommitDataRequests()) during a batching period, any
33966   // accumulated commits up to that point will be sent to the service
33967   // immediately. And when the batching period ends, the commits that occurred
33968   // after the immediate flush will also be sent to the service.
33969   //
33970   // If the duration has already been set to a non-zero value before this method
33971   // is called, and there is already a scheduled flush with the previously-set
33972   // duration, the new duration will take effect after the scheduled flush
33973   // occurs.
33974   //
33975   // If |batch_commits_duration_ms| is non-zero, batched data that hasn't been
33976   // sent could be lost at the end of a tracing session. To avoid this,
33977   // producers should make sure that FlushPendingCommitDataRequests is called
33978   // after the last TraceWriter write and before the service has stopped
33979   // listening for commits from the tracing session's data sources (i.e.
33980   // data sources should stop asynchronously, see
33981   // DataSourceDescriptor.will_notify_on_stop=true).
33982   virtual void SetBatchCommitsDuration(uint32_t batch_commits_duration_ms) = 0;
33983 
33984   // Called to enable direct producer-side patching of chunks that have not yet
33985   // been committed to the service. The return value indicates whether direct
33986   // patching was successfully enabled. It will be true if
33987   // SharedMemoryArbiter::SetDirectSMBPatchingSupportedByService has been called
33988   // and false otherwise.
33989   virtual bool EnableDirectSMBPatching() = 0;
33990 
33991   // When the producer and service live in separate processes, this method
33992   // should be called if the producer receives an
33993   // InitializeConnectionResponse.direct_smb_patching_supported set to true by
33994   // the service (see producer_port.proto) .
33995   //
33996   // In the in-process case, the service will always support direct SMB patching
33997   // and this method should always be called.
33998   virtual void SetDirectSMBPatchingSupportedByService() = 0;
33999 
34000   // Forces an immediate commit of the completed packets, without waiting for
34001   // the next task or for a batching period to end. Should only be called while
34002   // bound.
34003   virtual void FlushPendingCommitDataRequests(
34004       std::function<void()> callback = {}) = 0;
34005 
34006   // Attempts to shut down this arbiter. This function prevents new trace
34007   // writers from being created for this this arbiter, but if there are any
34008   // existing trace writers, the shutdown cannot proceed and this funtion
34009   // returns false. The caller should not delete the arbiter before all of its
34010   // associated trace writers have been destroyed and this function returns
34011   // true.
34012   virtual bool TryShutdown() = 0;
34013 
34014   // Create a bound arbiter instance. Args:
34015   // |SharedMemory|: the shared memory buffer to use.
34016   // |page_size|: a multiple of 4KB that defines the granularity of tracing
34017   // pages. See tradeoff considerations in shared_memory_abi.h.
34018   // |ProducerEndpoint|: The service's producer endpoint used e.g. to commit
34019   // chunks and register trace writers.
34020   // |TaskRunner|: Task runner for perfetto's main thread, which executes the
34021   // OnPagesCompleteCallback and IPC calls to the |ProducerEndpoint|.
34022   //
34023   // Implemented in src/core/shared_memory_arbiter_impl.cc.
34024   static std::unique_ptr<SharedMemoryArbiter> CreateInstance(
34025       SharedMemory*,
34026       size_t page_size,
34027       TracingService::ProducerEndpoint*,
34028       base::TaskRunner*);
34029 
34030   // Create an unbound arbiter instance, which should later be bound to a
34031   // ProducerEndpoint and TaskRunner by calling BindToProducerEndpoint(). The
34032   // returned arbiter will ONLY support trace writers with
34033   // BufferExhaustedPolicy::kDrop.
34034   //
34035   // An unbound SharedMemoryArbiter can be used to write to a producer-created
34036   // SharedMemory buffer before the producer connects to the tracing service.
34037   // The producer can then pass this SMB to the service when it connects (see
34038   // TracingService::ConnectProducer).
34039   //
34040   // To trace into the SMB before the service starts the tracing session, trace
34041   // writers can be obtained via CreateStartupTraceWriter() and later associated
34042   // with a target buffer via BindStartupTargetBuffer(), once the target buffer
34043   // is known.
34044   //
34045   // Implemented in src/core/shared_memory_arbiter_impl.cc. See CreateInstance()
34046   // for comments about the arguments.
34047   static std::unique_ptr<SharedMemoryArbiter> CreateUnboundInstance(
34048       SharedMemory*,
34049       size_t page_size);
34050 };
34051 
34052 }  // namespace perfetto
34053 
34054 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ARBITER_H_
34055 /*
34056  * Copyright (C) 2017 The Android Open Source Project
34057  *
34058  * Licensed under the Apache License, Version 2.0 (the "License");
34059  * you may not use this file except in compliance with the License.
34060  * You may obtain a copy of the License at
34061  *
34062  *      http://www.apache.org/licenses/LICENSE-2.0
34063  *
34064  * Unless required by applicable law or agreed to in writing, software
34065  * distributed under the License is distributed on an "AS IS" BASIS,
34066  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
34067  * See the License for the specific language governing permissions and
34068  * limitations under the License.
34069  */
34070 
34071 #ifndef SRC_TRACING_CORE_SHARED_MEMORY_ARBITER_IMPL_H_
34072 #define SRC_TRACING_CORE_SHARED_MEMORY_ARBITER_IMPL_H_
34073 
34074 #include <stdint.h>
34075 
34076 #include <functional>
34077 #include <map>
34078 #include <memory>
34079 #include <mutex>
34080 #include <vector>
34081 
34082 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
34083 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
34084 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
34085 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
34086 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
34087 // gen_amalgamated expanded: #include "src/tracing/core/id_allocator.h"
34088 
34089 namespace perfetto {
34090 
34091 class PatchList;
34092 class Patch;
34093 class TraceWriter;
34094 class TraceWriterImpl;
34095 
34096 namespace base {
34097 class TaskRunner;
34098 }  // namespace base
34099 
34100 // This class handles the shared memory buffer on the producer side. It is used
34101 // to obtain thread-local chunks and to partition pages from several threads.
34102 // There is one arbiter instance per Producer.
34103 // This class is thread-safe and uses locks to do so. Data sources are supposed
34104 // to interact with this sporadically, only when they run out of space on their
34105 // current thread-local chunk.
34106 //
34107 // When the arbiter is created using CreateUnboundInstance(), the following
34108 // state transitions are possible:
34109 //
34110 //   [ !fully_bound_, !endpoint_, 0 unbound buffer reservations ]
34111 //       |     |
34112 //       |     | CreateStartupTraceWriter(buf)
34113 //       |     |  buffer reservations += buf
34114 //       |     |
34115 //       |     |             ----
34116 //       |     |            |    | CreateStartupTraceWriter(buf)
34117 //       |     |            |    |  buffer reservations += buf
34118 //       |     V            |    V
34119 //       |   [ !fully_bound_, !endpoint_, >=1 unbound buffer reservations ]
34120 //       |                                                |
34121 //       |                       BindToProducerEndpoint() |
34122 //       |                                                |
34123 //       | BindToProducerEndpoint()                       |
34124 //       |                                                V
34125 //       |   [ !fully_bound_, endpoint_, >=1 unbound buffer reservations ]
34126 //       |   A    |    A                               |     A
34127 //       |   |    |    |                               |     |
34128 //       |   |     ----                                |     |
34129 //       |   |    CreateStartupTraceWriter(buf)        |     |
34130 //       |   |     buffer reservations += buf          |     |
34131 //       |   |                                         |     |
34132 //       |   | CreateStartupTraceWriter(buf)           |     |
34133 //       |   |  where buf is not yet bound             |     |
34134 //       |   |  buffer reservations += buf             |     | (yes)
34135 //       |   |                                         |     |
34136 //       |   |        BindStartupTargetBuffer(buf, id) |-----
34137 //       |   |           buffer reservations -= buf    | reservations > 0?
34138 //       |   |                                         |
34139 //       |   |                                         | (no)
34140 //       V   |                                         V
34141 //       [ fully_bound_, endpoint_, 0 unbound buffer reservations ]
34142 //          |    A
34143 //          |    | CreateStartupTraceWriter(buf)
34144 //          |    |  where buf is already bound
34145 //           ----
34146 class SharedMemoryArbiterImpl : public SharedMemoryArbiter {
34147  public:
34148   // See SharedMemoryArbiter::CreateInstance(). |start|, |size| define the
34149   // boundaries of the shared memory buffer. ProducerEndpoint and TaskRunner may
34150   // be |nullptr| if created unbound, see
34151   // SharedMemoryArbiter::CreateUnboundInstance().
34152   SharedMemoryArbiterImpl(void* start,
34153                           size_t size,
34154                           size_t page_size,
34155                           TracingService::ProducerEndpoint*,
34156                           base::TaskRunner*);
34157 
34158   // Returns a new Chunk to write tracing data. Depending on the provided
34159   // BufferExhaustedPolicy, this may return an invalid chunk if no valid free
34160   // chunk could be found in the SMB.
34161   SharedMemoryABI::Chunk GetNewChunk(const SharedMemoryABI::ChunkHeader&,
34162                                      BufferExhaustedPolicy,
34163                                      size_t size_hint = 0);
34164 
34165   // Puts back a Chunk that has been completed and sends a request to the
34166   // service to move it to the central tracing buffer. |target_buffer| is the
34167   // absolute trace buffer ID where the service should move the chunk onto (the
34168   // producer is just to copy back the same number received in the
34169   // DataSourceConfig upon the StartDataSource() reques).
34170   // PatchList is a pointer to the list of patches for previous chunks. The
34171   // first patched entries will be removed from the patched list and sent over
34172   // to the service in the same CommitData() IPC request.
34173   void ReturnCompletedChunk(SharedMemoryABI::Chunk,
34174                             MaybeUnboundBufferID target_buffer,
34175                             PatchList*);
34176 
34177   // Send a request to the service to apply completed patches from |patch_list|.
34178   // |writer_id| is the ID of the TraceWriter that calls this method,
34179   // |target_buffer| is the global trace buffer ID of its target buffer.
34180   void SendPatches(WriterID writer_id,
34181                    MaybeUnboundBufferID target_buffer,
34182                    PatchList* patch_list);
34183 
shmem_abi_for_testing()34184   SharedMemoryABI* shmem_abi_for_testing() { return &shmem_abi_; }
34185 
set_default_layout_for_testing(SharedMemoryABI::PageLayout l)34186   static void set_default_layout_for_testing(SharedMemoryABI::PageLayout l) {
34187     default_page_layout = l;
34188   }
34189 
34190   // SharedMemoryArbiter implementation.
34191   // See include/perfetto/tracing/core/shared_memory_arbiter.h for comments.
34192   std::unique_ptr<TraceWriter> CreateTraceWriter(
34193       BufferID target_buffer,
34194       BufferExhaustedPolicy = BufferExhaustedPolicy::kDefault) override;
34195   std::unique_ptr<TraceWriter> CreateStartupTraceWriter(
34196       uint16_t target_buffer_reservation_id) override;
34197   void BindToProducerEndpoint(TracingService::ProducerEndpoint*,
34198                               base::TaskRunner*) override;
34199   void BindStartupTargetBuffer(uint16_t target_buffer_reservation_id,
34200                                BufferID target_buffer_id) override;
34201   void AbortStartupTracingForReservation(
34202       uint16_t target_buffer_reservation_id) override;
34203   void NotifyFlushComplete(FlushRequestID) override;
34204 
34205   void SetBatchCommitsDuration(uint32_t batch_commits_duration_ms) override;
34206 
34207   bool EnableDirectSMBPatching() override;
34208 
34209   void SetDirectSMBPatchingSupportedByService() override;
34210 
34211   void FlushPendingCommitDataRequests(
34212       std::function<void()> callback = {}) override;
34213   bool TryShutdown() override;
34214 
task_runner() const34215   base::TaskRunner* task_runner() const { return task_runner_; }
page_size() const34216   size_t page_size() const { return shmem_abi_.page_size(); }
num_pages() const34217   size_t num_pages() const { return shmem_abi_.num_pages(); }
34218 
GetWeakPtr() const34219   base::WeakPtr<SharedMemoryArbiterImpl> GetWeakPtr() const {
34220     return weak_ptr_factory_.GetWeakPtr();
34221   }
34222 
34223  private:
34224   friend class TraceWriterImpl;
34225   friend class StartupTraceWriterTest;
34226   friend class SharedMemoryArbiterImplTest;
34227 
34228   struct TargetBufferReservation {
34229     bool resolved = false;
34230     BufferID target_buffer = kInvalidBufferId;
34231   };
34232 
34233   // Placeholder for the actual target buffer ID of a startup target buffer
34234   // reservation ID in |target_buffer_reservations_|.
34235   static constexpr BufferID kInvalidBufferId = 0;
34236 
34237   static SharedMemoryABI::PageLayout default_page_layout;
34238 
34239   SharedMemoryArbiterImpl(const SharedMemoryArbiterImpl&) = delete;
34240   SharedMemoryArbiterImpl& operator=(const SharedMemoryArbiterImpl&) = delete;
34241 
34242   void UpdateCommitDataRequest(SharedMemoryABI::Chunk chunk,
34243                                WriterID writer_id,
34244                                MaybeUnboundBufferID target_buffer,
34245                                PatchList* patch_list);
34246 
34247   // Search the chunks that are being batched in |commit_data_req_| for a chunk
34248   // that needs patching and that matches the provided |writer_id| and
34249   // |patch.chunk_id|. If found, apply |patch| to that chunk, and if
34250   // |chunk_needs_more_patching| is true, clear the needs patching flag of the
34251   // chunk and mark it as complete - to allow the service to read it (and other
34252   // chunks after it) during scraping. Returns true if the patch was applied,
34253   // false otherwise.
34254   //
34255   // Note: the caller must be holding |lock_| for the duration of the call.
34256   bool TryDirectPatchLocked(WriterID writer_id,
34257                             const Patch& patch,
34258                             bool chunk_needs_more_patching);
34259   std::unique_ptr<TraceWriter> CreateTraceWriterInternal(
34260       MaybeUnboundBufferID target_buffer,
34261       BufferExhaustedPolicy);
34262 
34263   // Called by the TraceWriter destructor.
34264   void ReleaseWriterID(WriterID);
34265 
34266   void BindStartupTargetBufferImpl(std::unique_lock<std::mutex> scoped_lock,
34267                                    uint16_t target_buffer_reservation_id,
34268                                    BufferID target_buffer_id);
34269 
34270   // If any flush callbacks were queued up while the arbiter or any target
34271   // buffer reservation was unbound, this wraps the pending callbacks into a new
34272   // std::function and returns it. Otherwise returns an invalid std::function.
34273   std::function<void()> TakePendingFlushCallbacksLocked();
34274 
34275   // Replace occurrences of target buffer reservation IDs in |commit_data_req_|
34276   // with their respective actual BufferIDs if they were already bound. Returns
34277   // true iff all occurrences were replaced.
34278   bool ReplaceCommitPlaceholderBufferIdsLocked();
34279 
34280   // Update and return |fully_bound_| based on the arbiter's |pending_writers_|
34281   // state.
34282   bool UpdateFullyBoundLocked();
34283 
34284   const bool initially_bound_;
34285 
34286   // Only accessed on |task_runner_| after the producer endpoint was bound.
34287   TracingService::ProducerEndpoint* producer_endpoint_ = nullptr;
34288 
34289   // --- Begin lock-protected members ---
34290 
34291   std::mutex lock_;
34292 
34293   base::TaskRunner* task_runner_ = nullptr;
34294   SharedMemoryABI shmem_abi_;
34295   size_t page_idx_ = 0;
34296   std::unique_ptr<CommitDataRequest> commit_data_req_;
34297   size_t bytes_pending_commit_ = 0;  // SUM(chunk.size() : commit_data_req_).
34298   IdAllocator<WriterID> active_writer_ids_;
34299   bool did_shutdown_ = false;
34300 
34301   // Whether the arbiter itself and all startup target buffer reservations are
34302   // bound. Note that this can become false again later if a new target buffer
34303   // reservation is created by calling CreateStartupTraceWriter() with a new
34304   // reservation id.
34305   bool fully_bound_;
34306 
34307   // IDs of writers and their assigned target buffers that should be registered
34308   // with the service after the arbiter and/or their startup target buffer is
34309   // bound.
34310   std::map<WriterID, MaybeUnboundBufferID> pending_writers_;
34311 
34312   // Callbacks for flush requests issued while the arbiter or a target buffer
34313   // reservation was unbound.
34314   std::vector<std::function<void()>> pending_flush_callbacks_;
34315 
34316   // See SharedMemoryArbiter::SetBatchCommitsDuration.
34317   uint32_t batch_commits_duration_ms_ = 0;
34318 
34319   // See SharedMemoryArbiter::EnableDirectSMBPatching.
34320   bool direct_patching_enabled_ = false;
34321 
34322   // See SharedMemoryArbiter::SetDirectSMBPatchingSupportedByService.
34323   bool direct_patching_supported_by_service_ = false;
34324 
34325   // Indicates whether we have already scheduled a delayed flush for the
34326   // purposes of batching. Set to true at the beginning of a batching period and
34327   // cleared at the end of the period. Immediate flushes that happen during a
34328   // batching period will empty the |commit_data_req| (triggering an immediate
34329   // IPC to the service), but will not clear this flag and the
34330   // previously-scheduled delayed flush will still occur at the end of the
34331   // batching period.
34332   bool delayed_flush_scheduled_ = false;
34333 
34334   // Stores target buffer reservations for writers created via
34335   // CreateStartupTraceWriter(). A bound reservation sets
34336   // TargetBufferReservation::resolved to true and is associated with the actual
34337   // BufferID supplied in BindStartupTargetBuffer().
34338   //
34339   // TODO(eseckler): Clean up entries from this map. This would probably require
34340   // a method in SharedMemoryArbiter that allows a producer to invalidate a
34341   // reservation ID.
34342   std::map<MaybeUnboundBufferID, TargetBufferReservation>
34343       target_buffer_reservations_;
34344 
34345   // --- End lock-protected members ---
34346 
34347   // Keep at the end.
34348   base::WeakPtrFactory<SharedMemoryArbiterImpl> weak_ptr_factory_;
34349 };
34350 
34351 }  // namespace perfetto
34352 
34353 #endif  // SRC_TRACING_CORE_SHARED_MEMORY_ARBITER_IMPL_H_
34354 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/commit_data_request.h
34355 /*
34356  * Copyright (C) 2017 The Android Open Source Project
34357  *
34358  * Licensed under the Apache License, Version 2.0 (the "License");
34359  * you may not use this file except in compliance with the License.
34360  * You may obtain a copy of the License at
34361  *
34362  *      http://www.apache.org/licenses/LICENSE-2.0
34363  *
34364  * Unless required by applicable law or agreed to in writing, software
34365  * distributed under the License is distributed on an "AS IS" BASIS,
34366  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
34367  * See the License for the specific language governing permissions and
34368  * limitations under the License.
34369  */
34370 
34371 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_COMMIT_DATA_REQUEST_H_
34372 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_COMMIT_DATA_REQUEST_H_
34373 
34374 // Creates the aliases in the ::perfetto namespace, doing things like:
34375 // using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
34376 // See comments in forward_decls.h for the historical reasons of this
34377 // indirection layer.
34378 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
34379 
34380 // gen_amalgamated expanded: #include "protos/perfetto/common/commit_data_request.gen.h"
34381 
34382 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_COMMIT_DATA_REQUEST_H_
34383 // gen_amalgamated begin header: src/tracing/core/trace_writer_impl.h
34384 // gen_amalgamated begin header: src/tracing/core/patch_list.h
34385 /*
34386  * Copyright (C) 2018 The Android Open Source Project
34387  *
34388  * Licensed under the Apache License, Version 2.0 (the "License");
34389  * you may not use this file except in compliance with the License.
34390  * You may obtain a copy of the License at
34391  *
34392  *      http://www.apache.org/licenses/LICENSE-2.0
34393  *
34394  * Unless required by applicable law or agreed to in writing, software
34395  * distributed under the License is distributed on an "AS IS" BASIS,
34396  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
34397  * See the License for the specific language governing permissions and
34398  * limitations under the License.
34399  */
34400 
34401 #ifndef SRC_TRACING_CORE_PATCH_LIST_H_
34402 #define SRC_TRACING_CORE_PATCH_LIST_H_
34403 
34404 #include <array>
34405 #include <forward_list>
34406 
34407 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
34408 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
34409 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
34410 
34411 namespace perfetto {
34412 
34413 // Used to handle the backfilling of the headers (the |size_field|) of nested
34414 // messages when a proto is fragmented over several chunks. These patches are
34415 // sent out-of-band to the tracing service, after having returned the initial
34416 // chunks of the fragment.
34417 // TODO(crbug.com/904477): Re-disable the move constructors when all usses of
34418 // this class have been fixed.
34419 class Patch {
34420  public:
34421   using PatchContent = std::array<uint8_t, SharedMemoryABI::kPacketHeaderSize>;
Patch(ChunkID c,uint16_t o)34422   Patch(ChunkID c, uint16_t o) : chunk_id(c), offset(o) {}
34423   Patch(const Patch&) = default;  // For tests.
34424 
34425   const ChunkID chunk_id;
34426   const uint16_t offset;
34427   PatchContent size_field{};
34428 
34429   // |size_field| contains a varint. Any varint must start with != 0. Even in
34430   // the case we want to encode a size == 0, protozero will write a redundant
34431   // varint for that, that is [0x80, 0x80, 0x80, 0x00]. So the first byte is 0
34432   // iff we never wrote any varint into that.
is_patched() const34433   bool is_patched() const { return size_field[0] != 0; }
34434 
34435   // For tests.
operator ==(const Patch & o) const34436   bool operator==(const Patch& o) const {
34437     return chunk_id == o.chunk_id && offset == o.offset &&
34438            size_field == o.size_field;
34439   }
34440 
34441  private:
34442   Patch& operator=(const Patch&) = delete;
34443 };
34444 
34445 // Note: the protozero::Message(s) will take pointers to the |size_field| of
34446 // these entries. This container must guarantee that the Patch objects are never
34447 // moved around (i.e. cannot be a vector because of reallocations can change
34448 // addresses of pre-existing entries).
34449 class PatchList {
34450  public:
34451   using ListType = std::forward_list<Patch>;
34452   using value_type = ListType::value_type;          // For gtest.
34453   using const_iterator = ListType::const_iterator;  // For gtest.
34454 
PatchList()34455   PatchList() : last_(list_.before_begin()) {}
34456 
emplace_back(ChunkID chunk_id,uint16_t offset)34457   Patch* emplace_back(ChunkID chunk_id, uint16_t offset) {
34458     PERFETTO_DCHECK(empty() || last_->chunk_id != chunk_id ||
34459                     offset >= last_->offset + sizeof(Patch::PatchContent));
34460     last_ = list_.emplace_after(last_, chunk_id, offset);
34461     return &*last_;
34462   }
34463 
pop_front()34464   void pop_front() {
34465     PERFETTO_DCHECK(!list_.empty());
34466     list_.pop_front();
34467     if (empty())
34468       last_ = list_.before_begin();
34469   }
34470 
front() const34471   const Patch& front() const {
34472     PERFETTO_DCHECK(!list_.empty());
34473     return list_.front();
34474   }
34475 
back() const34476   const Patch& back() const {
34477     PERFETTO_DCHECK(!list_.empty());
34478     return *last_;
34479   }
34480 
begin() const34481   ListType::const_iterator begin() const { return list_.begin(); }
end() const34482   ListType::const_iterator end() const { return list_.end(); }
empty() const34483   bool empty() const { return list_.empty(); }
34484 
34485  private:
34486   ListType list_;
34487   ListType::iterator last_;
34488 };
34489 
34490 }  // namespace perfetto
34491 
34492 #endif  // SRC_TRACING_CORE_PATCH_LIST_H_
34493 /*
34494  * Copyright (C) 2017 The Android Open Source Project
34495  *
34496  * Licensed under the Apache License, Version 2.0 (the "License");
34497  * you may not use this file except in compliance with the License.
34498  * You may obtain a copy of the License at
34499  *
34500  *      http://www.apache.org/licenses/LICENSE-2.0
34501  *
34502  * Unless required by applicable law or agreed to in writing, software
34503  * distributed under the License is distributed on an "AS IS" BASIS,
34504  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
34505  * See the License for the specific language governing permissions and
34506  * limitations under the License.
34507  */
34508 
34509 #ifndef SRC_TRACING_CORE_TRACE_WRITER_IMPL_H_
34510 #define SRC_TRACING_CORE_TRACE_WRITER_IMPL_H_
34511 
34512 // gen_amalgamated expanded: #include "perfetto/base/proc_utils.h"
34513 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
34514 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
34515 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
34516 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
34517 // gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
34518 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
34519 // gen_amalgamated expanded: #include "perfetto/protozero/root_message.h"
34520 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
34521 // gen_amalgamated expanded: #include "perfetto/tracing/buffer_exhausted_policy.h"
34522 // gen_amalgamated expanded: #include "src/tracing/core/patch_list.h"
34523 
34524 namespace perfetto {
34525 
34526 class SharedMemoryArbiterImpl;
34527 
34528 // See //include/perfetto/tracing/core/trace_writer.h for docs.
34529 class TraceWriterImpl : public TraceWriter,
34530                         public protozero::ScatteredStreamWriter::Delegate {
34531  public:
34532   // TracePacketHandle is defined in trace_writer.h
34533   TraceWriterImpl(SharedMemoryArbiterImpl*,
34534                   WriterID,
34535                   MaybeUnboundBufferID buffer_id,
34536                   BufferExhaustedPolicy);
34537   ~TraceWriterImpl() override;
34538 
34539   // TraceWriter implementation. See documentation in trace_writer.h.
34540   TracePacketHandle NewTracePacket() override;
34541   void Flush(std::function<void()> callback = {}) override;
34542   WriterID writer_id() const override;
written() const34543   uint64_t written() const override {
34544     return protobuf_stream_writer_.written();
34545   }
34546 
ResetChunkForTesting()34547   void ResetChunkForTesting() { cur_chunk_ = SharedMemoryABI::Chunk(); }
drop_packets_for_testing() const34548   bool drop_packets_for_testing() const { return drop_packets_; }
34549 
34550  private:
34551   TraceWriterImpl(const TraceWriterImpl&) = delete;
34552   TraceWriterImpl& operator=(const TraceWriterImpl&) = delete;
34553 
34554   // ScatteredStreamWriter::Delegate implementation.
34555   protozero::ContiguousMemoryRange GetNewBuffer() override;
34556 
34557   // The per-producer arbiter that coordinates access to the shared memory
34558   // buffer from several threads.
34559   SharedMemoryArbiterImpl* const shmem_arbiter_;
34560 
34561   // ID of the current writer.
34562   const WriterID id_;
34563 
34564   // This is copied into the commit request by SharedMemoryArbiter. See comments
34565   // in data_source_config.proto for |target_buffer|. If this is a reservation
34566   // for a buffer ID in case of a startup trace writer, SharedMemoryArbiterImpl
34567   // will also translate the reservation ID to the actual buffer ID.
34568   const MaybeUnboundBufferID target_buffer_;
34569 
34570   // Whether GetNewChunk() should stall or return an invalid chunk if the SMB is
34571   // exhausted.
34572   const BufferExhaustedPolicy buffer_exhausted_policy_;
34573 
34574   // Monotonic (% wrapping) sequence id of the chunk. Together with the WriterID
34575   // this allows the Service to reconstruct the linear sequence of packets.
34576   ChunkID next_chunk_id_ = 0;
34577 
34578   // The chunk we are holding onto (if any).
34579   SharedMemoryABI::Chunk cur_chunk_;
34580 
34581   // Passed to protozero message to write directly into |cur_chunk_|. It
34582   // keeps track of the write pointer. It calls us back (GetNewBuffer()) when
34583   // |cur_chunk_| is filled.
34584   protozero::ScatteredStreamWriter protobuf_stream_writer_;
34585 
34586   // The packet returned via NewTracePacket(). Its owned by this class,
34587   // TracePacketHandle has just a pointer to it.
34588   std::unique_ptr<protozero::RootMessage<protos::pbzero::TracePacket>>
34589       cur_packet_;
34590 
34591   // The start address of |cur_packet_| within |cur_chunk_|. Used to figure out
34592   // fragments sizes when a TracePacket write is interrupted by GetNewBuffer().
34593   uint8_t* cur_fragment_start_ = nullptr;
34594 
34595   // true if we received a call to GetNewBuffer() after NewTracePacket(),
34596   // false if GetNewBuffer() happened during NewTracePacket() prologue, while
34597   // starting the TracePacket header.
34598   bool fragmenting_packet_ = false;
34599 
34600   // Set to |true| when the current chunk contains the maximum number of packets
34601   // a chunk can contain. When this is |true|, the next packet requires starting
34602   // a new chunk.
34603   bool reached_max_packets_per_chunk_ = false;
34604 
34605   // If we fail to acquire a new chunk when the arbiter operates in
34606   // SharedMemory::BufferExhaustedPolicy::kDrop mode, the trace writer enters a
34607   // mode in which data is written to a local garbage chunk and dropped.
34608   bool drop_packets_ = false;
34609 
34610   // Whether the trace writer should try to acquire a new chunk from the SMB
34611   // when the next TracePacket is started because it filled the garbage chunk at
34612   // least once since the last attempt.
34613   bool retry_new_chunk_after_packet_ = false;
34614 
34615   // Points to the size field of the last packet we wrote to the current chunk.
34616   // If the chunk was already returned, this is reset to |nullptr|.
34617   uint8_t* last_packet_size_field_ = nullptr;
34618 
34619   // When a packet is fragmented across different chunks, the |size_field| of
34620   // the outstanding nested protobuf messages is redirected onto Patch entries
34621   // in this list at the time the Chunk is returned (because at that point we
34622   // have to release the ownership of the current Chunk). This list will be
34623   // later sent out-of-band to the tracing service, who will patch the required
34624   // chunks, if they are still around.
34625   PatchList patch_list_;
34626 
34627   // PID of the process that created the trace writer. Used for a DCHECK that
34628   // aims to detect unsupported process forks while tracing.
34629   const base::PlatformProcessId process_id_;
34630 };
34631 
34632 }  // namespace perfetto
34633 
34634 #endif  // SRC_TRACING_CORE_TRACE_WRITER_IMPL_H_
34635 /*
34636  * Copyright (C) 2017 The Android Open Source Project
34637  *
34638  * Licensed under the Apache License, Version 2.0 (the "License");
34639  * you may not use this file except in compliance with the License.
34640  * You may obtain a copy of the License at
34641  *
34642  *      http://www.apache.org/licenses/LICENSE-2.0
34643  *
34644  * Unless required by applicable law or agreed to in writing, software
34645  * distributed under the License is distributed on an "AS IS" BASIS,
34646  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
34647  * See the License for the specific language governing permissions and
34648  * limitations under the License.
34649  */
34650 
34651 // gen_amalgamated expanded: #include "src/tracing/core/shared_memory_arbiter_impl.h"
34652 
34653 #include <algorithm>
34654 #include <limits>
34655 #include <utility>
34656 
34657 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
34658 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
34659 // gen_amalgamated expanded: #include "perfetto/base/time.h"
34660 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/commit_data_request.h"
34661 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
34662 // gen_amalgamated expanded: #include "src/tracing/core/null_trace_writer.h"
34663 // gen_amalgamated expanded: #include "src/tracing/core/trace_writer_impl.h"
34664 
34665 namespace perfetto {
34666 
34667 using Chunk = SharedMemoryABI::Chunk;
34668 
34669 namespace {
34670 static_assert(sizeof(BufferID) == sizeof(uint16_t),
34671               "The MaybeUnboundBufferID logic requires BufferID not to grow "
34672               "above uint16_t.");
34673 
MakeTargetBufferIdForReservation(uint16_t reservation_id)34674 MaybeUnboundBufferID MakeTargetBufferIdForReservation(uint16_t reservation_id) {
34675   // Reservation IDs are stored in the upper bits.
34676   PERFETTO_CHECK(reservation_id > 0);
34677   return static_cast<MaybeUnboundBufferID>(reservation_id) << 16;
34678 }
34679 
IsReservationTargetBufferId(MaybeUnboundBufferID buffer_id)34680 bool IsReservationTargetBufferId(MaybeUnboundBufferID buffer_id) {
34681   return (buffer_id >> 16) > 0;
34682 }
34683 }  // namespace
34684 
34685 // static
34686 SharedMemoryABI::PageLayout SharedMemoryArbiterImpl::default_page_layout =
34687     SharedMemoryABI::PageLayout::kPageDiv1;
34688 
34689 // static
34690 constexpr BufferID SharedMemoryArbiterImpl::kInvalidBufferId;
34691 
34692 // static
CreateInstance(SharedMemory * shared_memory,size_t page_size,TracingService::ProducerEndpoint * producer_endpoint,base::TaskRunner * task_runner)34693 std::unique_ptr<SharedMemoryArbiter> SharedMemoryArbiter::CreateInstance(
34694     SharedMemory* shared_memory,
34695     size_t page_size,
34696     TracingService::ProducerEndpoint* producer_endpoint,
34697     base::TaskRunner* task_runner) {
34698   return std::unique_ptr<SharedMemoryArbiterImpl>(
34699       new SharedMemoryArbiterImpl(shared_memory->start(), shared_memory->size(),
34700                                   page_size, producer_endpoint, task_runner));
34701 }
34702 
34703 // static
CreateUnboundInstance(SharedMemory * shared_memory,size_t page_size)34704 std::unique_ptr<SharedMemoryArbiter> SharedMemoryArbiter::CreateUnboundInstance(
34705     SharedMemory* shared_memory,
34706     size_t page_size) {
34707   return std::unique_ptr<SharedMemoryArbiterImpl>(new SharedMemoryArbiterImpl(
34708       shared_memory->start(), shared_memory->size(), page_size,
34709       /*producer_endpoint=*/nullptr, /*task_runner=*/nullptr));
34710 }
34711 
SharedMemoryArbiterImpl(void * start,size_t size,size_t page_size,TracingService::ProducerEndpoint * producer_endpoint,base::TaskRunner * task_runner)34712 SharedMemoryArbiterImpl::SharedMemoryArbiterImpl(
34713     void* start,
34714     size_t size,
34715     size_t page_size,
34716     TracingService::ProducerEndpoint* producer_endpoint,
34717     base::TaskRunner* task_runner)
34718     : initially_bound_(task_runner && producer_endpoint),
34719       producer_endpoint_(producer_endpoint),
34720       task_runner_(task_runner),
34721       shmem_abi_(reinterpret_cast<uint8_t*>(start), size, page_size),
34722       active_writer_ids_(kMaxWriterID),
34723       fully_bound_(initially_bound_),
34724       weak_ptr_factory_(this) {}
34725 
GetNewChunk(const SharedMemoryABI::ChunkHeader & header,BufferExhaustedPolicy buffer_exhausted_policy,size_t size_hint)34726 Chunk SharedMemoryArbiterImpl::GetNewChunk(
34727     const SharedMemoryABI::ChunkHeader& header,
34728     BufferExhaustedPolicy buffer_exhausted_policy,
34729     size_t size_hint) {
34730   PERFETTO_DCHECK(size_hint == 0);  // Not implemented yet.
34731   // If initially unbound, we do not support stalling. In theory, we could
34732   // support stalling for TraceWriters created after the arbiter and startup
34733   // buffer reservations were bound, but to avoid raciness between the creation
34734   // of startup writers and binding, we categorically forbid kStall mode.
34735   PERFETTO_DCHECK(initially_bound_ ||
34736                   buffer_exhausted_policy == BufferExhaustedPolicy::kDrop);
34737 
34738   int stall_count = 0;
34739   unsigned stall_interval_us = 0;
34740   bool task_runner_runs_on_current_thread = false;
34741   static const unsigned kMaxStallIntervalUs = 100000;
34742   static const int kLogAfterNStalls = 3;
34743   static const int kFlushCommitsAfterEveryNStalls = 2;
34744   static const int kAssertAtNStalls = 100;
34745 
34746   for (;;) {
34747     // TODO(primiano): Probably this lock is not really required and this code
34748     // could be rewritten leveraging only the Try* atomic operations in
34749     // SharedMemoryABI. But let's not be too adventurous for the moment.
34750     {
34751       std::unique_lock<std::mutex> scoped_lock(lock_);
34752 
34753       task_runner_runs_on_current_thread =
34754           task_runner_ && task_runner_->RunsTasksOnCurrentThread();
34755 
34756       // If more than half of the SMB.size() is filled with completed chunks for
34757       // which we haven't notified the service yet (i.e. they are still enqueued
34758       // in |commit_data_req_|), force a synchronous CommitDataRequest() even if
34759       // we acquire a chunk, to reduce the likeliness of stalling the writer.
34760       //
34761       // We can only do this if we're writing on the same thread that we access
34762       // the producer endpoint on, since we cannot notify the producer endpoint
34763       // to commit synchronously on a different thread. Attempting to flush
34764       // synchronously on another thread will lead to subtle bugs caused by
34765       // out-of-order commit requests (crbug.com/919187#c28).
34766       bool should_commit_synchronously =
34767           task_runner_runs_on_current_thread &&
34768           buffer_exhausted_policy == BufferExhaustedPolicy::kStall &&
34769           commit_data_req_ && bytes_pending_commit_ >= shmem_abi_.size() / 2;
34770 
34771       const size_t initial_page_idx = page_idx_;
34772       for (size_t i = 0; i < shmem_abi_.num_pages(); i++) {
34773         page_idx_ = (initial_page_idx + i) % shmem_abi_.num_pages();
34774         bool is_new_page = false;
34775 
34776         // TODO(primiano): make the page layout dynamic.
34777         auto layout = SharedMemoryArbiterImpl::default_page_layout;
34778 
34779         if (shmem_abi_.is_page_free(page_idx_)) {
34780           // TODO(primiano): Use the |size_hint| here to decide the layout.
34781           is_new_page = shmem_abi_.TryPartitionPage(page_idx_, layout);
34782         }
34783         uint32_t free_chunks;
34784         if (is_new_page) {
34785           free_chunks = (1 << SharedMemoryABI::kNumChunksForLayout[layout]) - 1;
34786         } else {
34787           free_chunks = shmem_abi_.GetFreeChunks(page_idx_);
34788         }
34789 
34790         for (uint32_t chunk_idx = 0; free_chunks;
34791              chunk_idx++, free_chunks >>= 1) {
34792           if (!(free_chunks & 1))
34793             continue;
34794           // We found a free chunk.
34795           Chunk chunk = shmem_abi_.TryAcquireChunkForWriting(
34796               page_idx_, chunk_idx, &header);
34797           if (!chunk.is_valid())
34798             continue;
34799           if (stall_count > kLogAfterNStalls) {
34800             PERFETTO_LOG("Recovered from stall after %d iterations",
34801                          stall_count);
34802           }
34803 
34804           if (should_commit_synchronously) {
34805             // We can't flush while holding the lock.
34806             scoped_lock.unlock();
34807             FlushPendingCommitDataRequests();
34808             return chunk;
34809           } else {
34810             return chunk;
34811           }
34812         }
34813       }
34814     }  // scoped_lock
34815 
34816     if (buffer_exhausted_policy == BufferExhaustedPolicy::kDrop) {
34817       PERFETTO_DLOG("Shared memory buffer exhaused, returning invalid Chunk!");
34818       return Chunk();
34819     }
34820 
34821     PERFETTO_DCHECK(initially_bound_);
34822 
34823     // All chunks are taken (either kBeingWritten by us or kBeingRead by the
34824     // Service).
34825     if (stall_count++ == kLogAfterNStalls) {
34826       PERFETTO_LOG("Shared memory buffer overrun! Stalling");
34827     }
34828 
34829     if (stall_count == kAssertAtNStalls) {
34830       PERFETTO_FATAL(
34831           "Shared memory buffer max stall count exceeded; possible deadlock");
34832     }
34833 
34834     // If the IPC thread itself is stalled because the current process has
34835     // filled up the SMB, we need to make sure that the service can process and
34836     // purge the chunks written by our process, by flushing any pending commit
34837     // requests. Because other threads in our process can continue to
34838     // concurrently grab, fill and commit any chunks purged by the service, it
34839     // is possible that the SMB remains full and the IPC thread remains stalled,
34840     // needing to flush the concurrently queued up commits again. This is
34841     // particularly likely with in-process perfetto service where the IPC thread
34842     // is the service thread. To avoid remaining stalled forever in such a
34843     // situation, we attempt to flush periodically after every N stalls.
34844     if (stall_count % kFlushCommitsAfterEveryNStalls == 0 &&
34845         task_runner_runs_on_current_thread) {
34846       // TODO(primiano): sending the IPC synchronously is a temporary workaround
34847       // until the backpressure logic in probes_producer is sorted out. Until
34848       // then the risk is that we stall the message loop waiting for the tracing
34849       // service to consume the shared memory buffer (SMB) and, for this reason,
34850       // never run the task that tells the service to purge the SMB. This must
34851       // happen iff we are on the IPC thread, not doing this will cause
34852       // deadlocks, doing this on the wrong thread causes out-of-order data
34853       // commits (crbug.com/919187#c28).
34854       FlushPendingCommitDataRequests();
34855     } else {
34856       base::SleepMicroseconds(stall_interval_us);
34857       stall_interval_us =
34858           std::min(kMaxStallIntervalUs, (stall_interval_us + 1) * 8);
34859     }
34860   }
34861 }
34862 
ReturnCompletedChunk(Chunk chunk,MaybeUnboundBufferID target_buffer,PatchList * patch_list)34863 void SharedMemoryArbiterImpl::ReturnCompletedChunk(
34864     Chunk chunk,
34865     MaybeUnboundBufferID target_buffer,
34866     PatchList* patch_list) {
34867   PERFETTO_DCHECK(chunk.is_valid());
34868   const WriterID writer_id = chunk.writer_id();
34869   UpdateCommitDataRequest(std::move(chunk), writer_id, target_buffer,
34870                           patch_list);
34871 }
34872 
SendPatches(WriterID writer_id,MaybeUnboundBufferID target_buffer,PatchList * patch_list)34873 void SharedMemoryArbiterImpl::SendPatches(WriterID writer_id,
34874                                           MaybeUnboundBufferID target_buffer,
34875                                           PatchList* patch_list) {
34876   PERFETTO_DCHECK(!patch_list->empty() && patch_list->front().is_patched());
34877   UpdateCommitDataRequest(Chunk(), writer_id, target_buffer, patch_list);
34878 }
34879 
UpdateCommitDataRequest(Chunk chunk,WriterID writer_id,MaybeUnboundBufferID target_buffer,PatchList * patch_list)34880 void SharedMemoryArbiterImpl::UpdateCommitDataRequest(
34881     Chunk chunk,
34882     WriterID writer_id,
34883     MaybeUnboundBufferID target_buffer,
34884     PatchList* patch_list) {
34885   // Note: chunk will be invalid if the call came from SendPatches().
34886   base::TaskRunner* task_runner_to_post_delayed_callback_on = nullptr;
34887   // The delay with which the flush will be posted.
34888   uint32_t flush_delay_ms = 0;
34889   base::WeakPtr<SharedMemoryArbiterImpl> weak_this;
34890   {
34891     std::lock_guard<std::mutex> scoped_lock(lock_);
34892 
34893     if (!commit_data_req_) {
34894       commit_data_req_.reset(new CommitDataRequest());
34895 
34896       // Flushing the commit is only supported while we're |fully_bound_|. If we
34897       // aren't, we'll flush when |fully_bound_| is updated.
34898       if (fully_bound_ && !delayed_flush_scheduled_) {
34899         weak_this = weak_ptr_factory_.GetWeakPtr();
34900         task_runner_to_post_delayed_callback_on = task_runner_;
34901         flush_delay_ms = batch_commits_duration_ms_;
34902         delayed_flush_scheduled_ = true;
34903       }
34904     }
34905 
34906     // If a valid chunk is specified, return it and attach it to the request.
34907     if (chunk.is_valid()) {
34908       PERFETTO_DCHECK(chunk.writer_id() == writer_id);
34909       uint8_t chunk_idx = chunk.chunk_idx();
34910       bytes_pending_commit_ += chunk.size();
34911       size_t page_idx;
34912       // If the chunk needs patching, it should not be marked as complete yet,
34913       // because this would indicate to the service that the producer will not
34914       // be writing to it anymore, while the producer might still apply patches
34915       // to the chunk later on. In particular, when re-reading (e.g. because of
34916       // periodic scraping) a completed chunk, the service expects the flags of
34917       // that chunk not to be removed between reads. So, let's say the producer
34918       // marked the chunk as complete here and the service then read it for the
34919       // first time. If the producer then fully patched the chunk, thus removing
34920       // the kChunkNeedsPatching flag, and the service re-read the chunk after
34921       // the patching, the service would be thrown off by the removed flag.
34922       if (direct_patching_enabled_ &&
34923           (chunk.GetPacketCountAndFlags().second &
34924            SharedMemoryABI::ChunkHeader::kChunkNeedsPatching)) {
34925         page_idx = shmem_abi_.GetPageAndChunkIndex(std::move(chunk)).first;
34926       } else {
34927         // If the chunk doesn't need patching, we can mark it as complete
34928         // immediately. This allows the service to read it in full while
34929         // scraping, which would not be the case if the chunk was left in a
34930         // kChunkBeingWritten state.
34931         page_idx = shmem_abi_.ReleaseChunkAsComplete(std::move(chunk));
34932       }
34933 
34934       // DO NOT access |chunk| after this point, it has been std::move()-d
34935       // above.
34936       CommitDataRequest::ChunksToMove* ctm =
34937           commit_data_req_->add_chunks_to_move();
34938       ctm->set_page(static_cast<uint32_t>(page_idx));
34939       ctm->set_chunk(chunk_idx);
34940       ctm->set_target_buffer(target_buffer);
34941     }
34942 
34943     // Process the completed patches for previous chunks from the |patch_list|.
34944     CommitDataRequest::ChunkToPatch* last_patch_req = nullptr;
34945     while (!patch_list->empty() && patch_list->front().is_patched()) {
34946       Patch curr_patch = patch_list->front();
34947       patch_list->pop_front();
34948       // Patches for the same chunk are contiguous in the |patch_list|. So, to
34949       // determine if there are any other patches that apply to the chunk that
34950       // is being patched, check if the next patch in the |patch_list| applies
34951       // to the same chunk.
34952       bool chunk_needs_more_patching =
34953           !patch_list->empty() &&
34954           patch_list->front().chunk_id == curr_patch.chunk_id;
34955 
34956       if (direct_patching_enabled_ &&
34957           TryDirectPatchLocked(writer_id, curr_patch,
34958                                chunk_needs_more_patching)) {
34959         continue;
34960       }
34961 
34962       // The chunk that this patch applies to has already been released to the
34963       // service, so it cannot be patches here. Add the patch to the commit data
34964       // request, so that it can be sent to the service and applied there.
34965       if (!last_patch_req ||
34966           last_patch_req->chunk_id() != curr_patch.chunk_id) {
34967         last_patch_req = commit_data_req_->add_chunks_to_patch();
34968         last_patch_req->set_writer_id(writer_id);
34969         last_patch_req->set_chunk_id(curr_patch.chunk_id);
34970         last_patch_req->set_target_buffer(target_buffer);
34971       }
34972       auto* patch = last_patch_req->add_patches();
34973       patch->set_offset(curr_patch.offset);
34974       patch->set_data(&curr_patch.size_field[0], curr_patch.size_field.size());
34975     }
34976 
34977     // Patches are enqueued in the |patch_list| in order and are notified to
34978     // the service when the chunk is returned. The only case when the current
34979     // patch list is incomplete is if there is an unpatched entry at the head of
34980     // the |patch_list| that belongs to the same ChunkID as the last one we are
34981     // about to send to the service.
34982     if (last_patch_req && !patch_list->empty() &&
34983         patch_list->front().chunk_id == last_patch_req->chunk_id()) {
34984       last_patch_req->set_has_more_patches(true);
34985     }
34986 
34987     // If the buffer is filling up or if we are given a patch for a chunk
34988     // that was already sent to the service, we don't want to wait for the next
34989     // delayed flush to happen and we flush immediately. Otherwise, if we
34990     // accumulate the patch and a crash occurs before the patch is sent, the
34991     // service will not know of the patch and won't be able to reconstruct the
34992     // trace.
34993     if (fully_bound_ &&
34994         (last_patch_req || bytes_pending_commit_ >= shmem_abi_.size() / 2)) {
34995       weak_this = weak_ptr_factory_.GetWeakPtr();
34996       task_runner_to_post_delayed_callback_on = task_runner_;
34997       flush_delay_ms = 0;
34998     }
34999   }  // scoped_lock(lock_)
35000 
35001   // We shouldn't post tasks while locked.
35002   // |task_runner_to_post_delayed_callback_on| remains valid after unlocking,
35003   // because |task_runner_| is never reset.
35004   if (task_runner_to_post_delayed_callback_on) {
35005     task_runner_to_post_delayed_callback_on->PostDelayedTask(
35006         [weak_this] {
35007           if (!weak_this)
35008             return;
35009           {
35010             std::lock_guard<std::mutex> scoped_lock(weak_this->lock_);
35011             // Clear |delayed_flush_scheduled_|, allowing the next call to
35012             // UpdateCommitDataRequest to start another batching period.
35013             weak_this->delayed_flush_scheduled_ = false;
35014           }
35015           weak_this->FlushPendingCommitDataRequests();
35016         },
35017         flush_delay_ms);
35018   }
35019 }
35020 
TryDirectPatchLocked(WriterID writer_id,const Patch & patch,bool chunk_needs_more_patching)35021 bool SharedMemoryArbiterImpl::TryDirectPatchLocked(
35022     WriterID writer_id,
35023     const Patch& patch,
35024     bool chunk_needs_more_patching) {
35025   // Search the chunks that are being batched in |commit_data_req_| for a chunk
35026   // that needs patching and that matches the provided |writer_id| and
35027   // |patch.chunk_id|. Iterate |commit_data_req_| in reverse, since
35028   // |commit_data_req_| is appended to at the end with newly-returned chunks,
35029   // and patches are more likely to apply to chunks that have been returned
35030   // recently.
35031   SharedMemoryABI::Chunk chunk;
35032   bool chunk_found = false;
35033   auto& chunks_to_move = commit_data_req_->chunks_to_move();
35034   for (auto ctm_it = chunks_to_move.rbegin(); ctm_it != chunks_to_move.rend();
35035        ++ctm_it) {
35036     uint32_t layout = shmem_abi_.GetPageLayout(ctm_it->page());
35037     auto chunk_state =
35038         shmem_abi_.GetChunkStateFromLayout(layout, ctm_it->chunk());
35039     // Note: the subset of |commit_data_req_| chunks that still need patching is
35040     // also the subset of chunks that are still being written to. The rest of
35041     // the chunks in |commit_data_req_| do not need patching and have already
35042     // been marked as complete.
35043     if (chunk_state != SharedMemoryABI::kChunkBeingWritten)
35044       continue;
35045 
35046     chunk =
35047         shmem_abi_.GetChunkUnchecked(ctm_it->page(), layout, ctm_it->chunk());
35048     if (chunk.writer_id() == writer_id &&
35049         chunk.header()->chunk_id.load(std::memory_order_relaxed) ==
35050             patch.chunk_id) {
35051       chunk_found = true;
35052       break;
35053     }
35054   }
35055 
35056   if (!chunk_found) {
35057     // The chunk has already been committed to the service and the patch cannot
35058     // be applied in the producer.
35059     return false;
35060   }
35061 
35062   // Apply the patch.
35063   size_t page_idx;
35064   uint8_t chunk_idx;
35065   std::tie(page_idx, chunk_idx) = shmem_abi_.GetPageAndChunkIndex(chunk);
35066   PERFETTO_DCHECK(shmem_abi_.GetChunkState(page_idx, chunk_idx) ==
35067                   SharedMemoryABI::ChunkState::kChunkBeingWritten);
35068   auto chunk_begin = chunk.payload_begin();
35069   uint8_t* ptr = chunk_begin + patch.offset;
35070   PERFETTO_CHECK(ptr <= chunk.end() - SharedMemoryABI::kPacketHeaderSize);
35071   // DCHECK that we are writing into a zero-filled size field and not into
35072   // valid data. It relies on ScatteredStreamWriter::ReserveBytes() to
35073   // zero-fill reservations in debug builds.
35074   const char zero[SharedMemoryABI::kPacketHeaderSize]{};
35075   PERFETTO_DCHECK(memcmp(ptr, &zero, SharedMemoryABI::kPacketHeaderSize) == 0);
35076 
35077   memcpy(ptr, &patch.size_field[0], SharedMemoryABI::kPacketHeaderSize);
35078 
35079   if (!chunk_needs_more_patching) {
35080     // Mark that the chunk doesn't need more patching and mark it as complete,
35081     // as the producer will not write to it anymore. This allows the service to
35082     // read the chunk in full while scraping, which would not be the case if the
35083     // chunk was left in a kChunkBeingWritten state.
35084     chunk.ClearNeedsPatchingFlag();
35085     shmem_abi_.ReleaseChunkAsComplete(std::move(chunk));
35086   }
35087 
35088   return true;
35089 }
35090 
SetBatchCommitsDuration(uint32_t batch_commits_duration_ms)35091 void SharedMemoryArbiterImpl::SetBatchCommitsDuration(
35092     uint32_t batch_commits_duration_ms) {
35093   std::lock_guard<std::mutex> scoped_lock(lock_);
35094   batch_commits_duration_ms_ = batch_commits_duration_ms;
35095 }
35096 
EnableDirectSMBPatching()35097 bool SharedMemoryArbiterImpl::EnableDirectSMBPatching() {
35098   std::lock_guard<std::mutex> scoped_lock(lock_);
35099   if (!direct_patching_supported_by_service_) {
35100     return false;
35101   }
35102 
35103   return direct_patching_enabled_ = true;
35104 }
35105 
SetDirectSMBPatchingSupportedByService()35106 void SharedMemoryArbiterImpl::SetDirectSMBPatchingSupportedByService() {
35107   std::lock_guard<std::mutex> scoped_lock(lock_);
35108   direct_patching_supported_by_service_ = true;
35109 }
35110 
35111 // This function is quite subtle. When making changes keep in mind these two
35112 // challenges:
35113 // 1) If the producer stalls and we happen to be on the |task_runner_| IPC
35114 //    thread (or, for in-process cases, on the same thread where
35115 //    TracingServiceImpl lives), the CommitData() call must be synchronous and
35116 //    not posted, to avoid deadlocks.
35117 // 2) When different threads hit this function, we must guarantee that we don't
35118 //    accidentally make commits out of order. See commit 4e4fe8f56ef and
35119 //    crbug.com/919187 for more context.
FlushPendingCommitDataRequests(std::function<void ()> callback)35120 void SharedMemoryArbiterImpl::FlushPendingCommitDataRequests(
35121     std::function<void()> callback) {
35122   std::unique_ptr<CommitDataRequest> req;
35123   {
35124     std::unique_lock<std::mutex> scoped_lock(lock_);
35125 
35126     // Flushing is only supported while |fully_bound_|, and there may still be
35127     // unbound startup trace writers. If so, skip the commit for now - it'll be
35128     // done when |fully_bound_| is updated.
35129     if (!fully_bound_) {
35130       if (callback)
35131         pending_flush_callbacks_.push_back(callback);
35132       return;
35133     }
35134 
35135     // May be called by TraceWriterImpl on any thread.
35136     base::TaskRunner* task_runner = task_runner_;
35137     if (!task_runner->RunsTasksOnCurrentThread()) {
35138       // We shouldn't post a task while holding a lock. |task_runner| remains
35139       // valid after unlocking, because |task_runner_| is never reset.
35140       scoped_lock.unlock();
35141 
35142       auto weak_this = weak_ptr_factory_.GetWeakPtr();
35143       task_runner->PostTask([weak_this, callback] {
35144         if (weak_this)
35145           weak_this->FlushPendingCommitDataRequests(std::move(callback));
35146       });
35147       return;
35148     }
35149 
35150     // |commit_data_req_| could have become a nullptr, for example when a forced
35151     // sync flush happens in GetNewChunk().
35152     if (commit_data_req_) {
35153       // Make sure any placeholder buffer IDs from StartupWriters are replaced
35154       // before sending the request.
35155       bool all_placeholders_replaced =
35156           ReplaceCommitPlaceholderBufferIdsLocked();
35157       // We're |fully_bound_|, thus all writers are bound and all placeholders
35158       // should have been replaced.
35159       PERFETTO_DCHECK(all_placeholders_replaced);
35160 
35161       // In order to allow patching in the producer we delay the kChunkComplete
35162       // transition and keep batched chunks in the kChunkBeingWritten state.
35163       // Since we are about to notify the service of all batched chunks, it will
35164       // not be possible to apply any more patches to them and we need to move
35165       // them to kChunkComplete - otherwise the service won't look at them.
35166       for (auto& ctm : commit_data_req_->chunks_to_move()) {
35167         uint32_t layout = shmem_abi_.GetPageLayout(ctm.page());
35168         auto chunk_state =
35169             shmem_abi_.GetChunkStateFromLayout(layout, ctm.chunk());
35170         // Note: the subset of |commit_data_req_| chunks that still need
35171         // patching is also the subset of chunks that are still being written
35172         // to. The rest of the chunks in |commit_data_req_| do not need patching
35173         // and have already been marked as complete.
35174         if (chunk_state != SharedMemoryABI::kChunkBeingWritten)
35175           continue;
35176 
35177         SharedMemoryABI::Chunk chunk =
35178             shmem_abi_.GetChunkUnchecked(ctm.page(), layout, ctm.chunk());
35179         shmem_abi_.ReleaseChunkAsComplete(std::move(chunk));
35180       }
35181 
35182       req = std::move(commit_data_req_);
35183       bytes_pending_commit_ = 0;
35184     }
35185   }  // scoped_lock
35186 
35187   if (req) {
35188     producer_endpoint_->CommitData(*req, callback);
35189   } else if (callback) {
35190     // If |req| was nullptr, it means that an enqueued deferred commit was
35191     // executed just before this. At this point send an empty commit request
35192     // to the service, just to linearize with it and give the guarantee to the
35193     // caller that the data has been flushed into the service.
35194     producer_endpoint_->CommitData(CommitDataRequest(), std::move(callback));
35195   }
35196 }
35197 
TryShutdown()35198 bool SharedMemoryArbiterImpl::TryShutdown() {
35199   std::lock_guard<std::mutex> scoped_lock(lock_);
35200   did_shutdown_ = true;
35201   // Shutdown is safe if there are no active trace writers for this arbiter.
35202   return active_writer_ids_.IsEmpty();
35203 }
35204 
CreateTraceWriter(BufferID target_buffer,BufferExhaustedPolicy buffer_exhausted_policy)35205 std::unique_ptr<TraceWriter> SharedMemoryArbiterImpl::CreateTraceWriter(
35206     BufferID target_buffer,
35207     BufferExhaustedPolicy buffer_exhausted_policy) {
35208   PERFETTO_CHECK(target_buffer > 0);
35209   return CreateTraceWriterInternal(target_buffer, buffer_exhausted_policy);
35210 }
35211 
CreateStartupTraceWriter(uint16_t target_buffer_reservation_id)35212 std::unique_ptr<TraceWriter> SharedMemoryArbiterImpl::CreateStartupTraceWriter(
35213     uint16_t target_buffer_reservation_id) {
35214   PERFETTO_CHECK(!initially_bound_);
35215   return CreateTraceWriterInternal(
35216       MakeTargetBufferIdForReservation(target_buffer_reservation_id),
35217       BufferExhaustedPolicy::kDrop);
35218 }
35219 
BindToProducerEndpoint(TracingService::ProducerEndpoint * producer_endpoint,base::TaskRunner * task_runner)35220 void SharedMemoryArbiterImpl::BindToProducerEndpoint(
35221     TracingService::ProducerEndpoint* producer_endpoint,
35222     base::TaskRunner* task_runner) {
35223   PERFETTO_DCHECK(producer_endpoint && task_runner);
35224   PERFETTO_DCHECK(task_runner->RunsTasksOnCurrentThread());
35225   PERFETTO_CHECK(!initially_bound_);
35226 
35227   bool should_flush = false;
35228   std::function<void()> flush_callback;
35229   {
35230     std::lock_guard<std::mutex> scoped_lock(lock_);
35231     PERFETTO_CHECK(!fully_bound_);
35232     PERFETTO_CHECK(!producer_endpoint_ && !task_runner_);
35233 
35234     producer_endpoint_ = producer_endpoint;
35235     task_runner_ = task_runner;
35236 
35237     // Now that we're bound to a task runner, also reset the WeakPtrFactory to
35238     // it. Because this code runs on the task runner, the factory's weak
35239     // pointers will be valid on it.
35240     weak_ptr_factory_.Reset(this);
35241 
35242     // All writers registered so far should be startup trace writers, since
35243     // the producer cannot feasibly know the target buffer for any future
35244     // session yet.
35245     for (const auto& entry : pending_writers_) {
35246       PERFETTO_CHECK(IsReservationTargetBufferId(entry.second));
35247     }
35248 
35249     // If all buffer reservations are bound, we can flush pending commits.
35250     if (UpdateFullyBoundLocked()) {
35251       should_flush = true;
35252       flush_callback = TakePendingFlushCallbacksLocked();
35253     }
35254   }  // scoped_lock
35255 
35256   // Attempt to flush any pending commits (and run pending flush callbacks). If
35257   // there are none, this will have no effect. If we ended up in a race that
35258   // changed |fully_bound_| back to false, the commit will happen once we become
35259   // |fully_bound_| again.
35260   if (should_flush)
35261     FlushPendingCommitDataRequests(flush_callback);
35262 }
35263 
BindStartupTargetBuffer(uint16_t target_buffer_reservation_id,BufferID target_buffer_id)35264 void SharedMemoryArbiterImpl::BindStartupTargetBuffer(
35265     uint16_t target_buffer_reservation_id,
35266     BufferID target_buffer_id) {
35267   PERFETTO_DCHECK(target_buffer_id > 0);
35268   PERFETTO_CHECK(!initially_bound_);
35269 
35270   std::unique_lock<std::mutex> scoped_lock(lock_);
35271 
35272   // We should already be bound to an endpoint, but not fully bound.
35273   PERFETTO_CHECK(!fully_bound_);
35274   PERFETTO_CHECK(producer_endpoint_);
35275   PERFETTO_CHECK(task_runner_);
35276   PERFETTO_CHECK(task_runner_->RunsTasksOnCurrentThread());
35277 
35278   BindStartupTargetBufferImpl(std::move(scoped_lock),
35279                               target_buffer_reservation_id, target_buffer_id);
35280 }
35281 
AbortStartupTracingForReservation(uint16_t target_buffer_reservation_id)35282 void SharedMemoryArbiterImpl::AbortStartupTracingForReservation(
35283     uint16_t target_buffer_reservation_id) {
35284   PERFETTO_CHECK(!initially_bound_);
35285 
35286   std::unique_lock<std::mutex> scoped_lock(lock_);
35287 
35288   // If we are already bound to an arbiter, we may need to flush after aborting
35289   // the session, and thus should be running on the arbiter's task runner.
35290   if (task_runner_ && !task_runner_->RunsTasksOnCurrentThread()) {
35291     // We shouldn't post tasks while locked.
35292     auto* task_runner = task_runner_;
35293     scoped_lock.unlock();
35294 
35295     auto weak_this = weak_ptr_factory_.GetWeakPtr();
35296     task_runner->PostTask([weak_this, target_buffer_reservation_id]() {
35297       if (!weak_this)
35298         return;
35299       weak_this->AbortStartupTracingForReservation(
35300           target_buffer_reservation_id);
35301     });
35302     return;
35303   }
35304 
35305   PERFETTO_CHECK(!fully_bound_);
35306 
35307   // Bind the target buffer reservation to an invalid buffer (ID 0), so that
35308   // existing commits, as well as future commits (of currently acquired chunks),
35309   // will be released as free free by the service but otherwise ignored (i.e.
35310   // not copied into any valid target buffer).
35311   BindStartupTargetBufferImpl(std::move(scoped_lock),
35312                               target_buffer_reservation_id,
35313                               /*target_buffer_id=*/kInvalidBufferId);
35314 }
35315 
BindStartupTargetBufferImpl(std::unique_lock<std::mutex> scoped_lock,uint16_t target_buffer_reservation_id,BufferID target_buffer_id)35316 void SharedMemoryArbiterImpl::BindStartupTargetBufferImpl(
35317     std::unique_lock<std::mutex> scoped_lock,
35318     uint16_t target_buffer_reservation_id,
35319     BufferID target_buffer_id) {
35320   // We should already be bound to an endpoint if the target buffer is valid.
35321   PERFETTO_DCHECK((producer_endpoint_ && task_runner_) ||
35322                   target_buffer_id == kInvalidBufferId);
35323 
35324   MaybeUnboundBufferID reserved_id =
35325       MakeTargetBufferIdForReservation(target_buffer_reservation_id);
35326 
35327   bool should_flush = false;
35328   std::function<void()> flush_callback;
35329   std::vector<std::pair<WriterID, BufferID>> writers_to_register;
35330 
35331   TargetBufferReservation& reservation =
35332       target_buffer_reservations_[reserved_id];
35333   PERFETTO_CHECK(!reservation.resolved);
35334   reservation.resolved = true;
35335   reservation.target_buffer = target_buffer_id;
35336 
35337   // Collect trace writers associated with the reservation.
35338   for (auto it = pending_writers_.begin(); it != pending_writers_.end();) {
35339     if (it->second == reserved_id) {
35340       // No need to register writers that have an invalid target buffer.
35341       if (target_buffer_id != kInvalidBufferId) {
35342         writers_to_register.push_back(
35343             std::make_pair(it->first, target_buffer_id));
35344       }
35345       it = pending_writers_.erase(it);
35346     } else {
35347       it++;
35348     }
35349   }
35350 
35351   // If all buffer reservations are bound, we can flush pending commits.
35352   if (UpdateFullyBoundLocked()) {
35353     should_flush = true;
35354     flush_callback = TakePendingFlushCallbacksLocked();
35355   }
35356 
35357   scoped_lock.unlock();
35358 
35359   // Register any newly bound trace writers with the service.
35360   for (const auto& writer_and_target_buffer : writers_to_register) {
35361     producer_endpoint_->RegisterTraceWriter(writer_and_target_buffer.first,
35362                                             writer_and_target_buffer.second);
35363   }
35364 
35365   // Attempt to flush any pending commits (and run pending flush callbacks). If
35366   // there are none, this will have no effect. If we ended up in a race that
35367   // changed |fully_bound_| back to false, the commit will happen once we become
35368   // |fully_bound_| again.
35369   if (should_flush)
35370     FlushPendingCommitDataRequests(flush_callback);
35371 }
35372 
35373 std::function<void()>
TakePendingFlushCallbacksLocked()35374 SharedMemoryArbiterImpl::TakePendingFlushCallbacksLocked() {
35375   if (pending_flush_callbacks_.empty())
35376     return std::function<void()>();
35377 
35378   std::vector<std::function<void()>> pending_flush_callbacks;
35379   pending_flush_callbacks.swap(pending_flush_callbacks_);
35380   // Capture the callback list into the lambda by copy.
35381   return [pending_flush_callbacks]() {
35382     for (auto& callback : pending_flush_callbacks)
35383       callback();
35384   };
35385 }
35386 
NotifyFlushComplete(FlushRequestID req_id)35387 void SharedMemoryArbiterImpl::NotifyFlushComplete(FlushRequestID req_id) {
35388   base::TaskRunner* task_runner_to_commit_on = nullptr;
35389 
35390   {
35391     std::lock_guard<std::mutex> scoped_lock(lock_);
35392     // If a commit_data_req_ exists it means that somebody else already posted a
35393     // FlushPendingCommitDataRequests() task.
35394     if (!commit_data_req_) {
35395       commit_data_req_.reset(new CommitDataRequest());
35396 
35397       // Flushing the commit is only supported while we're |fully_bound_|. If we
35398       // aren't, we'll flush when |fully_bound_| is updated.
35399       if (fully_bound_)
35400         task_runner_to_commit_on = task_runner_;
35401     } else {
35402       // If there is another request queued and that also contains is a reply
35403       // to a flush request, reply with the highest id.
35404       req_id = std::max(req_id, commit_data_req_->flush_request_id());
35405     }
35406     commit_data_req_->set_flush_request_id(req_id);
35407   }  // scoped_lock
35408 
35409   // We shouldn't post tasks while locked. |task_runner_to_commit_on|
35410   // remains valid after unlocking, because |task_runner_| is never reset.
35411   if (task_runner_to_commit_on) {
35412     auto weak_this = weak_ptr_factory_.GetWeakPtr();
35413     task_runner_to_commit_on->PostTask([weak_this] {
35414       if (weak_this)
35415         weak_this->FlushPendingCommitDataRequests();
35416     });
35417   }
35418 }
35419 
CreateTraceWriterInternal(MaybeUnboundBufferID target_buffer,BufferExhaustedPolicy buffer_exhausted_policy)35420 std::unique_ptr<TraceWriter> SharedMemoryArbiterImpl::CreateTraceWriterInternal(
35421     MaybeUnboundBufferID target_buffer,
35422     BufferExhaustedPolicy buffer_exhausted_policy) {
35423   WriterID id;
35424   base::TaskRunner* task_runner_to_register_on = nullptr;
35425 
35426   {
35427     std::lock_guard<std::mutex> scoped_lock(lock_);
35428     if (did_shutdown_)
35429       return std::unique_ptr<TraceWriter>(new NullTraceWriter());
35430 
35431     id = active_writer_ids_.Allocate();
35432     if (!id)
35433       return std::unique_ptr<TraceWriter>(new NullTraceWriter());
35434 
35435     PERFETTO_DCHECK(!pending_writers_.count(id));
35436 
35437     if (IsReservationTargetBufferId(target_buffer)) {
35438       // If the reservation is new, mark it as unbound in
35439       // |target_buffer_reservations_|. Otherwise, if the reservation was
35440       // already bound, choose the bound buffer ID now.
35441       auto it_and_inserted = target_buffer_reservations_.insert(
35442           {target_buffer, TargetBufferReservation()});
35443       if (it_and_inserted.first->second.resolved)
35444         target_buffer = it_and_inserted.first->second.target_buffer;
35445     }
35446 
35447     if (IsReservationTargetBufferId(target_buffer)) {
35448       // The arbiter and/or startup buffer reservations are not bound yet, so
35449       // buffer the registration of the writer until after we're bound.
35450       pending_writers_[id] = target_buffer;
35451 
35452       // Mark the arbiter as not fully bound, since we now have at least one
35453       // unbound trace writer / target buffer reservation.
35454       fully_bound_ = false;
35455     } else if (target_buffer != kInvalidBufferId) {
35456       // Trace writer is bound, so arbiter should be bound to an endpoint, too.
35457       PERFETTO_CHECK(producer_endpoint_ && task_runner_);
35458       task_runner_to_register_on = task_runner_;
35459     }
35460   }  // scoped_lock
35461 
35462   // We shouldn't post tasks while locked. |task_runner_to_register_on|
35463   // remains valid after unlocking, because |task_runner_| is never reset.
35464   if (task_runner_to_register_on) {
35465     auto weak_this = weak_ptr_factory_.GetWeakPtr();
35466     task_runner_to_register_on->PostTask([weak_this, id, target_buffer] {
35467       if (weak_this)
35468         weak_this->producer_endpoint_->RegisterTraceWriter(id, target_buffer);
35469     });
35470   }
35471 
35472   return std::unique_ptr<TraceWriter>(
35473       new TraceWriterImpl(this, id, target_buffer, buffer_exhausted_policy));
35474 }
35475 
ReleaseWriterID(WriterID id)35476 void SharedMemoryArbiterImpl::ReleaseWriterID(WriterID id) {
35477   base::TaskRunner* task_runner = nullptr;
35478   {
35479     std::lock_guard<std::mutex> scoped_lock(lock_);
35480     active_writer_ids_.Free(id);
35481 
35482     auto it = pending_writers_.find(id);
35483     if (it != pending_writers_.end()) {
35484       // Writer hasn't been bound yet and thus also not yet registered with the
35485       // service.
35486       pending_writers_.erase(it);
35487       return;
35488     }
35489 
35490     // A trace writer from an aborted session may be destroyed before the
35491     // arbiter is bound to a task runner. In that case, it was never registered
35492     // with the service.
35493     if (!task_runner_)
35494       return;
35495 
35496     task_runner = task_runner_;
35497   }  // scoped_lock
35498 
35499   // We shouldn't post tasks while locked. |task_runner| remains valid after
35500   // unlocking, because |task_runner_| is never reset.
35501   auto weak_this = weak_ptr_factory_.GetWeakPtr();
35502   task_runner->PostTask([weak_this, id] {
35503     if (weak_this)
35504       weak_this->producer_endpoint_->UnregisterTraceWriter(id);
35505   });
35506 }
35507 
ReplaceCommitPlaceholderBufferIdsLocked()35508 bool SharedMemoryArbiterImpl::ReplaceCommitPlaceholderBufferIdsLocked() {
35509   if (!commit_data_req_)
35510     return true;
35511 
35512   bool all_placeholders_replaced = true;
35513   for (auto& chunk : *commit_data_req_->mutable_chunks_to_move()) {
35514     if (!IsReservationTargetBufferId(chunk.target_buffer()))
35515       continue;
35516     const auto it = target_buffer_reservations_.find(chunk.target_buffer());
35517     PERFETTO_DCHECK(it != target_buffer_reservations_.end());
35518     if (!it->second.resolved) {
35519       all_placeholders_replaced = false;
35520       continue;
35521     }
35522     chunk.set_target_buffer(it->second.target_buffer);
35523   }
35524   for (auto& chunk : *commit_data_req_->mutable_chunks_to_patch()) {
35525     if (!IsReservationTargetBufferId(chunk.target_buffer()))
35526       continue;
35527     const auto it = target_buffer_reservations_.find(chunk.target_buffer());
35528     PERFETTO_DCHECK(it != target_buffer_reservations_.end());
35529     if (!it->second.resolved) {
35530       all_placeholders_replaced = false;
35531       continue;
35532     }
35533     chunk.set_target_buffer(it->second.target_buffer);
35534   }
35535   return all_placeholders_replaced;
35536 }
35537 
UpdateFullyBoundLocked()35538 bool SharedMemoryArbiterImpl::UpdateFullyBoundLocked() {
35539   if (!producer_endpoint_) {
35540     PERFETTO_DCHECK(!fully_bound_);
35541     return false;
35542   }
35543   // We're fully bound if all target buffer reservations have a valid associated
35544   // BufferID.
35545   fully_bound_ = std::none_of(
35546       target_buffer_reservations_.begin(), target_buffer_reservations_.end(),
35547       [](std::pair<MaybeUnboundBufferID, TargetBufferReservation> entry) {
35548         return !entry.second.resolved;
35549       });
35550   return fully_bound_;
35551 }
35552 
35553 }  // namespace perfetto
35554 // gen_amalgamated begin source: src/tracing/core/trace_packet.cc
35555 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/trace_packet.h
35556 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/slice.h
35557 /*
35558  * Copyright (C) 2017 The Android Open Source Project
35559  *
35560  * Licensed under the Apache License, Version 2.0 (the "License");
35561  * you may not use this file except in compliance with the License.
35562  * You may obtain a copy of the License at
35563  *
35564  *      http://www.apache.org/licenses/LICENSE-2.0
35565  *
35566  * Unless required by applicable law or agreed to in writing, software
35567  * distributed under the License is distributed on an "AS IS" BASIS,
35568  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
35569  * See the License for the specific language governing permissions and
35570  * limitations under the License.
35571  */
35572 
35573 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_SLICE_H_
35574 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_SLICE_H_
35575 
35576 #include <stddef.h>
35577 #include <string.h>
35578 
35579 #include <memory>
35580 #include <string>
35581 #include <vector>
35582 
35583 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
35584 
35585 namespace perfetto {
35586 
35587 // A simple wrapper around a virtually contiguous memory range that contains a
35588 // TracePacket, or just a portion of it.
35589 struct Slice {
Sliceperfetto::Slice35590   Slice() : start(nullptr), size(0) {}
Sliceperfetto::Slice35591   Slice(const void* st, size_t sz) : start(st), size(sz) {}
35592   Slice(Slice&& other) noexcept = default;
35593 
35594   // Create a Slice which owns |size| bytes of memory.
Allocateperfetto::Slice35595   static Slice Allocate(size_t size) {
35596     Slice slice;
35597     slice.own_data_.reset(new uint8_t[size]);
35598     slice.start = &slice.own_data_[0];
35599     slice.size = size;
35600     return slice;
35601   }
35602 
TakeOwnershipperfetto::Slice35603   static Slice TakeOwnership(std::unique_ptr<uint8_t[]> buf, size_t size) {
35604     Slice slice;
35605     slice.own_data_ = std::move(buf);
35606     slice.start = &slice.own_data_[0];
35607     slice.size = size;
35608     return slice;
35609   }
35610 
own_dataperfetto::Slice35611   uint8_t* own_data() {
35612     PERFETTO_DCHECK(own_data_);
35613     return own_data_.get();
35614   }
35615 
35616   const void* start;
35617   size_t size;
35618 
35619  private:
35620   Slice(const Slice&) = delete;
35621   void operator=(const Slice&) = delete;
35622 
35623   std::unique_ptr<uint8_t[]> own_data_;
35624 };
35625 
35626 // TODO(primiano): most TracePacket(s) fit in a slice or two. We need something
35627 // a bit more clever here that has inline capacity for 2 slices and then uses a
35628 // std::forward_list or a std::vector for the less likely cases.
35629 using Slices = std::vector<Slice>;
35630 
35631 }  // namespace perfetto
35632 
35633 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_SLICE_H_
35634 /*
35635  * Copyright (C) 2017 The Android Open Source Project
35636  *
35637  * Licensed under the Apache License, Version 2.0 (the "License");
35638  * you may not use this file except in compliance with the License.
35639  * You may obtain a copy of the License at
35640  *
35641  *      http://www.apache.org/licenses/LICENSE-2.0
35642  *
35643  * Unless required by applicable law or agreed to in writing, software
35644  * distributed under the License is distributed on an "AS IS" BASIS,
35645  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
35646  * See the License for the specific language governing permissions and
35647  * limitations under the License.
35648  */
35649 
35650 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_PACKET_H_
35651 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_PACKET_H_
35652 
35653 #include <stddef.h>
35654 #include <memory>
35655 #include <tuple>
35656 
35657 // gen_amalgamated expanded: #include "perfetto/base/export.h"
35658 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
35659 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/slice.h"
35660 
35661 namespace perfetto {
35662 
35663 // A wrapper around a byte buffer that contains a protobuf-encoded TracePacket
35664 // (see trace_packet.proto). The TracePacket is decoded only if the Consumer
35665 // requests that. This is to allow Consumer(s) to just stream the packet over
35666 // the network or save it to a file without wasting time decoding it and without
35667 // needing to depend on libprotobuf or the trace_packet.pb.h header.
35668 // If the packets are saved / streamed and not just consumed locally, consumers
35669 // should ensure to preserve the unknown fields in the proto. A consumer, in
35670 // fact, might have an older version .proto which is newer on the producer.
35671 class PERFETTO_EXPORT TracePacket {
35672  public:
35673   using const_iterator = Slices::const_iterator;
35674 
35675   // The field id of protos::Trace::packet, static_assert()-ed in the unittest.
35676   static constexpr uint32_t kPacketFieldNumber = 1;
35677 
35678   // Maximum size of the preamble returned by GetProtoPreamble().
35679   static constexpr size_t kMaxPreambleBytes = 8;
35680 
35681   TracePacket();
35682   ~TracePacket();
35683   TracePacket(TracePacket&&) noexcept;
35684   TracePacket& operator=(TracePacket&&);
35685 
35686   // Accesses all the raw slices in the packet, for saving them to file/network.
slices() const35687   const Slices& slices() const { return slices_; }
35688 
35689   // Mutator, used only by the service and tests.
35690   void AddSlice(Slice);
35691 
35692   // Does not copy / take ownership of the memory of the slice. The TracePacket
35693   // will be valid only as long as the original buffer is valid.
35694   void AddSlice(const void* start, size_t size);
35695 
35696   // Total size of all slices.
size() const35697   size_t size() const { return size_; }
35698 
35699   // Generates a protobuf preamble suitable to represent this packet as a
35700   // repeated field within a root trace.proto message.
35701   // Returns a pointer to a buffer, owned by this class, containing the preamble
35702   // and its size.
35703   std::tuple<char*, size_t> GetProtoPreamble();
35704 
35705   // Returns the raw protobuf bytes of the slices, all stitched together into
35706   // a string. Only for testing.
35707   std::string GetRawBytesForTesting();
35708 
35709  private:
35710   TracePacket(const TracePacket&) = delete;
35711   TracePacket& operator=(const TracePacket&) = delete;
35712 
35713   Slices slices_;     // Not owned.
35714   size_t size_ = 0;   // SUM(slice.size for slice in slices_).
35715   char preamble_[kMaxPreambleBytes];  // Deliberately not initialized.
35716 
35717   // Remember to update the move operators and their unittest if adding new
35718   // fields. ConsumerIPCClientImpl::OnReadBuffersResponse() relies on
35719   // std::move(TracePacket) to clear up the moved-from instance.
35720 };
35721 
35722 }  // namespace perfetto
35723 
35724 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_PACKET_H_
35725 /*
35726  * Copyright (C) 2017 The Android Open Source Project
35727  *
35728  * Licensed under the Apache License, Version 2.0 (the "License");
35729  * you may not use this file except in compliance with the License.
35730  * You may obtain a copy of the License at
35731  *
35732  *      http://www.apache.org/licenses/LICENSE-2.0
35733  *
35734  * Unless required by applicable law or agreed to in writing, software
35735  * distributed under the License is distributed on an "AS IS" BASIS,
35736  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
35737  * See the License for the specific language governing permissions and
35738  * limitations under the License.
35739  */
35740 
35741 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
35742 
35743 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
35744 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
35745 
35746 namespace perfetto {
35747 
35748 TracePacket::TracePacket() = default;
35749 TracePacket::~TracePacket() = default;
35750 
TracePacket(TracePacket && other)35751 TracePacket::TracePacket(TracePacket&& other) noexcept {
35752   *this = std::move(other);
35753 }
35754 
operator =(TracePacket && other)35755 TracePacket& TracePacket::operator=(TracePacket&& other) {
35756   slices_ = std::move(other.slices_);
35757   other.slices_.clear();
35758   size_ = other.size_;
35759   other.size_ = 0;
35760   return *this;
35761 }
35762 
AddSlice(Slice slice)35763 void TracePacket::AddSlice(Slice slice) {
35764   size_ += slice.size;
35765   slices_.push_back(std::move(slice));
35766 }
35767 
AddSlice(const void * start,size_t size)35768 void TracePacket::AddSlice(const void* start, size_t size) {
35769   size_ += size;
35770   slices_.emplace_back(start, size);
35771 }
35772 
GetProtoPreamble()35773 std::tuple<char*, size_t> TracePacket::GetProtoPreamble() {
35774   using protozero::proto_utils::MakeTagLengthDelimited;
35775   using protozero::proto_utils::WriteVarInt;
35776   uint8_t* ptr = reinterpret_cast<uint8_t*>(&preamble_[0]);
35777 
35778   constexpr uint8_t tag = MakeTagLengthDelimited(kPacketFieldNumber);
35779   static_assert(tag < 0x80, "TracePacket tag should fit in one byte");
35780   *(ptr++) = tag;
35781 
35782   ptr = WriteVarInt(size(), ptr);
35783   size_t preamble_size = reinterpret_cast<uintptr_t>(ptr) -
35784                          reinterpret_cast<uintptr_t>(&preamble_[0]);
35785   PERFETTO_DCHECK(preamble_size <= sizeof(preamble_));
35786   return std::make_tuple(&preamble_[0], preamble_size);
35787 }
35788 
GetRawBytesForTesting()35789 std::string TracePacket::GetRawBytesForTesting() {
35790   std::string data;
35791   data.resize(size());
35792   size_t pos = 0;
35793   for (const Slice& slice : slices()) {
35794     PERFETTO_CHECK(pos + slice.size <= data.size());
35795     memcpy(&data[pos], slice.start, slice.size);
35796     pos += slice.size;
35797   }
35798   return data;
35799 }
35800 
35801 }  // namespace perfetto
35802 // gen_amalgamated begin source: src/tracing/core/trace_writer_impl.cc
35803 /*
35804  * Copyright (C) 2017 The Android Open Source Project
35805  *
35806  * Licensed under the Apache License, Version 2.0 (the "License");
35807  * you may not use this file except in compliance with the License.
35808  * You may obtain a copy of the License at
35809  *
35810  *      http://www.apache.org/licenses/LICENSE-2.0
35811  *
35812  * Unless required by applicable law or agreed to in writing, software
35813  * distributed under the License is distributed on an "AS IS" BASIS,
35814  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
35815  * See the License for the specific language governing permissions and
35816  * limitations under the License.
35817  */
35818 
35819 // gen_amalgamated expanded: #include "src/tracing/core/trace_writer_impl.h"
35820 
35821 #include <string.h>
35822 
35823 #include <algorithm>
35824 #include <type_traits>
35825 #include <utility>
35826 
35827 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
35828 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_annotations.h"
35829 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
35830 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
35831 // gen_amalgamated expanded: #include "perfetto/protozero/root_message.h"
35832 // gen_amalgamated expanded: #include "src/tracing/core/shared_memory_arbiter_impl.h"
35833 
35834 // gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
35835 
35836 using protozero::proto_utils::kMessageLengthFieldSize;
35837 using protozero::proto_utils::WriteRedundantVarInt;
35838 using ChunkHeader = perfetto::SharedMemoryABI::ChunkHeader;
35839 
35840 namespace perfetto {
35841 
35842 namespace {
35843 constexpr size_t kPacketHeaderSize = SharedMemoryABI::kPacketHeaderSize;
35844 uint8_t g_garbage_chunk[1024];
35845 }  // namespace
35846 
TraceWriterImpl(SharedMemoryArbiterImpl * shmem_arbiter,WriterID id,MaybeUnboundBufferID target_buffer,BufferExhaustedPolicy buffer_exhausted_policy)35847 TraceWriterImpl::TraceWriterImpl(SharedMemoryArbiterImpl* shmem_arbiter,
35848                                  WriterID id,
35849                                  MaybeUnboundBufferID target_buffer,
35850                                  BufferExhaustedPolicy buffer_exhausted_policy)
35851     : shmem_arbiter_(shmem_arbiter),
35852       id_(id),
35853       target_buffer_(target_buffer),
35854       buffer_exhausted_policy_(buffer_exhausted_policy),
35855       protobuf_stream_writer_(this),
35856       process_id_(base::GetProcessId()) {
35857   // TODO(primiano): we could handle the case of running out of TraceWriterID(s)
35858   // more gracefully and always return a no-op TracePacket in NewTracePacket().
35859   PERFETTO_CHECK(id_ != 0);
35860 
35861   cur_packet_.reset(new protozero::RootMessage<protos::pbzero::TracePacket>());
35862   cur_packet_->Finalize();  // To avoid the DCHECK in NewTracePacket().
35863 }
35864 
~TraceWriterImpl()35865 TraceWriterImpl::~TraceWriterImpl() {
35866   if (cur_chunk_.is_valid()) {
35867     cur_packet_->Finalize();
35868     Flush();
35869   }
35870   // This call may cause the shared memory arbiter (and the underlying memory)
35871   // to get asynchronously deleted if this was the last trace writer targeting
35872   // the arbiter and the arbiter was marked for shutdown.
35873   shmem_arbiter_->ReleaseWriterID(id_);
35874 }
35875 
Flush(std::function<void ()> callback)35876 void TraceWriterImpl::Flush(std::function<void()> callback) {
35877   // Flush() cannot be called in the middle of a TracePacket.
35878   PERFETTO_CHECK(cur_packet_->is_finalized());
35879 
35880   if (cur_chunk_.is_valid()) {
35881     shmem_arbiter_->ReturnCompletedChunk(std::move(cur_chunk_), target_buffer_,
35882                                          &patch_list_);
35883   } else {
35884     // When in stall mode, all patches should have been returned with the last
35885     // chunk, since the last packet was completed. In drop_packets_ mode, this
35886     // may not be the case because the packet may have been fragmenting when
35887     // SMB exhaustion occurred and |cur_chunk_| became invalid. In this case,
35888     // drop_packets_ should be true.
35889     PERFETTO_DCHECK(patch_list_.empty() || drop_packets_);
35890   }
35891 
35892   // Always issue the Flush request, even if there is nothing to flush, just
35893   // for the sake of getting the callback posted back.
35894   shmem_arbiter_->FlushPendingCommitDataRequests(callback);
35895   protobuf_stream_writer_.Reset({nullptr, nullptr});
35896 
35897   // |last_packet_size_field_| might have pointed into the chunk we returned.
35898   last_packet_size_field_ = nullptr;
35899 }
35900 
NewTracePacket()35901 TraceWriterImpl::TracePacketHandle TraceWriterImpl::NewTracePacket() {
35902   // If we hit this, the caller is calling NewTracePacket() without having
35903   // finalized the previous packet.
35904   PERFETTO_CHECK(cur_packet_->is_finalized());
35905   // If we hit this, this trace writer was created in a different process. This
35906   // likely means that the process forked while tracing was active, and the
35907   // forked child process tried to emit a trace event. This is not supported, as
35908   // it would lead to two processes writing to the same tracing SMB.
35909   PERFETTO_DCHECK(process_id_ == base::GetProcessId());
35910 
35911   fragmenting_packet_ = false;
35912 
35913   // Reserve space for the size of the message. Note: this call might re-enter
35914   // into this class invoking GetNewBuffer() if there isn't enough space or if
35915   // this is the very first call to NewTracePacket().
35916   static_assert(kPacketHeaderSize == kMessageLengthFieldSize,
35917                 "The packet header must match the Message header size");
35918 
35919   bool was_dropping_packets = drop_packets_;
35920 
35921   // It doesn't make sense to begin a packet that is going to fragment
35922   // immediately after (8 is just an arbitrary estimation on the minimum size of
35923   // a realistic packet).
35924   bool chunk_too_full =
35925       protobuf_stream_writer_.bytes_available() < kPacketHeaderSize + 8;
35926   if (chunk_too_full || reached_max_packets_per_chunk_ ||
35927       retry_new_chunk_after_packet_) {
35928     protobuf_stream_writer_.Reset(GetNewBuffer());
35929   }
35930 
35931   // Send any completed patches to the service to facilitate trace data
35932   // recovery by the service. This should only happen when we're completing
35933   // the first packet in a chunk which was a continuation from the previous
35934   // chunk, i.e. at most once per chunk.
35935   if (!patch_list_.empty() && patch_list_.front().is_patched()) {
35936     shmem_arbiter_->SendPatches(id_, target_buffer_, &patch_list_);
35937   }
35938 
35939   cur_packet_->Reset(&protobuf_stream_writer_);
35940   uint8_t* header = protobuf_stream_writer_.ReserveBytes(kPacketHeaderSize);
35941   memset(header, 0, kPacketHeaderSize);
35942   cur_packet_->set_size_field(header);
35943   last_packet_size_field_ = header;
35944 
35945   TracePacketHandle handle(cur_packet_.get());
35946   cur_fragment_start_ = protobuf_stream_writer_.write_ptr();
35947   fragmenting_packet_ = true;
35948 
35949   if (PERFETTO_LIKELY(!drop_packets_)) {
35950     uint16_t new_packet_count = cur_chunk_.IncrementPacketCount();
35951     reached_max_packets_per_chunk_ =
35952         new_packet_count == ChunkHeader::Packets::kMaxCount;
35953 
35954     if (PERFETTO_UNLIKELY(was_dropping_packets)) {
35955       // We've succeeded to get a new chunk from the SMB after we entered
35956       // drop_packets_ mode. Record a marker into the new packet to indicate the
35957       // data loss.
35958       cur_packet_->set_previous_packet_dropped(true);
35959     }
35960   }
35961 
35962   return handle;
35963 }
35964 
35965 // Called by the Message. We can get here in two cases:
35966 // 1. In the middle of writing a Message,
35967 // when |fragmenting_packet_| == true. In this case we want to update the
35968 // chunk header with a partial packet and start a new partial packet in the
35969 // new chunk.
35970 // 2. While calling ReserveBytes() for the packet header in NewTracePacket().
35971 // In this case |fragmenting_packet_| == false and we just want a new chunk
35972 // without creating any fragments.
GetNewBuffer()35973 protozero::ContiguousMemoryRange TraceWriterImpl::GetNewBuffer() {
35974   if (fragmenting_packet_ && drop_packets_) {
35975     // We can't write the remaining data of the fragmenting packet to a new
35976     // chunk, because we have already lost some of its data in the garbage
35977     // chunk. Thus, we will wrap around in the garbage chunk, wait until the
35978     // current packet was completed, and then attempt to get a new chunk from
35979     // the SMB again. Instead, if |drop_packets_| is true and
35980     // |fragmenting_packet_| is false, we try to acquire a valid chunk because
35981     // the SMB exhaustion might be resolved.
35982     retry_new_chunk_after_packet_ = true;
35983     return protozero::ContiguousMemoryRange{
35984         &g_garbage_chunk[0], &g_garbage_chunk[0] + sizeof(g_garbage_chunk)};
35985   }
35986 
35987   // Attempt to grab the next chunk before finalizing the current one, so that
35988   // we know whether we need to start dropping packets before writing the
35989   // current packet fragment's header.
35990   ChunkHeader::Packets packets = {};
35991   if (fragmenting_packet_) {
35992     packets.count = 1;
35993     packets.flags = ChunkHeader::kFirstPacketContinuesFromPrevChunk;
35994   }
35995 
35996   // The memory order of the stores below doesn't really matter. This |header|
35997   // is just a local temporary object. The GetNewChunk() call below will copy it
35998   // into the shared buffer with the proper barriers.
35999   ChunkHeader header = {};
36000   header.writer_id.store(id_, std::memory_order_relaxed);
36001   header.chunk_id.store(next_chunk_id_, std::memory_order_relaxed);
36002   header.packets.store(packets, std::memory_order_relaxed);
36003 
36004   SharedMemoryABI::Chunk new_chunk =
36005       shmem_arbiter_->GetNewChunk(header, buffer_exhausted_policy_);
36006   if (!new_chunk.is_valid()) {
36007     // Shared memory buffer exhausted, switch into |drop_packets_| mode. We'll
36008     // drop data until the garbage chunk has been filled once and then retry.
36009 
36010     // If we started a packet in one of the previous (valid) chunks, we need to
36011     // tell the service to discard it.
36012     if (fragmenting_packet_) {
36013       // We can only end up here if the previous chunk was a valid chunk,
36014       // because we never try to acquire a new chunk in |drop_packets_| mode
36015       // while fragmenting.
36016       PERFETTO_DCHECK(!drop_packets_);
36017 
36018       // Backfill the last fragment's header with an invalid size (too large),
36019       // so that the service's TraceBuffer throws out the incomplete packet.
36020       // It'll restart reading from the next chunk we submit.
36021       WriteRedundantVarInt(SharedMemoryABI::kPacketSizeDropPacket,
36022                            cur_packet_->size_field());
36023 
36024       // Reset the size field, since we should not write the current packet's
36025       // size anymore after this.
36026       cur_packet_->set_size_field(nullptr);
36027 
36028       // We don't set kLastPacketContinuesOnNextChunk or kChunkNeedsPatching on
36029       // the last chunk, because its last fragment will be discarded anyway.
36030       // However, the current packet fragment points to a valid |cur_chunk_| and
36031       // may have non-finalized nested messages which will continue in the
36032       // garbage chunk and currently still point into |cur_chunk_|. As we are
36033       // about to return |cur_chunk_|, we need to invalidate the size fields of
36034       // those nested messages. Normally we move them in the |patch_list_| (see
36035       // below) but in this case, it doesn't make sense to send patches for a
36036       // fragment that will be discarded for sure. Thus, we clean up any size
36037       // field references into |cur_chunk_|.
36038       for (auto* nested_msg = cur_packet_->nested_message(); nested_msg;
36039            nested_msg = nested_msg->nested_message()) {
36040         uint8_t* const cur_hdr = nested_msg->size_field();
36041 
36042         // If this is false the protozero Message has already been instructed to
36043         // write, upon Finalize(), its size into the patch list.
36044         bool size_field_points_within_chunk =
36045             cur_hdr >= cur_chunk_.payload_begin() &&
36046             cur_hdr + kMessageLengthFieldSize <= cur_chunk_.end();
36047 
36048         if (size_field_points_within_chunk)
36049           nested_msg->set_size_field(nullptr);
36050       }
36051     } else if (!drop_packets_ && last_packet_size_field_) {
36052       // If we weren't dropping packets before, we should indicate to the
36053       // service that we're about to lose data. We do this by invalidating the
36054       // size of the last packet in |cur_chunk_|. The service will record
36055       // statistics about packets with kPacketSizeDropPacket size.
36056       PERFETTO_DCHECK(cur_packet_->is_finalized());
36057       PERFETTO_DCHECK(cur_chunk_.is_valid());
36058 
36059       // |last_packet_size_field_| should point within |cur_chunk_|'s payload.
36060       PERFETTO_DCHECK(last_packet_size_field_ >= cur_chunk_.payload_begin() &&
36061                       last_packet_size_field_ + kMessageLengthFieldSize <=
36062                           cur_chunk_.end());
36063 
36064       WriteRedundantVarInt(SharedMemoryABI::kPacketSizeDropPacket,
36065                            last_packet_size_field_);
36066     }
36067 
36068     if (cur_chunk_.is_valid()) {
36069       shmem_arbiter_->ReturnCompletedChunk(std::move(cur_chunk_),
36070                                            target_buffer_, &patch_list_);
36071     }
36072 
36073     drop_packets_ = true;
36074     cur_chunk_ = SharedMemoryABI::Chunk();  // Reset to an invalid chunk.
36075     reached_max_packets_per_chunk_ = false;
36076     retry_new_chunk_after_packet_ = false;
36077     last_packet_size_field_ = nullptr;
36078 
36079     PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(&g_garbage_chunk,
36080                                         sizeof(g_garbage_chunk),
36081                                         "nobody reads the garbage chunk")
36082     return protozero::ContiguousMemoryRange{
36083         &g_garbage_chunk[0], &g_garbage_chunk[0] + sizeof(g_garbage_chunk)};
36084   }  // if (!new_chunk.is_valid())
36085 
36086   PERFETTO_DCHECK(new_chunk.is_valid());
36087 
36088   if (fragmenting_packet_) {
36089     // We should not be fragmenting a packet after we exited drop_packets_ mode,
36090     // because we only retry to get a new chunk when a fresh packet is started.
36091     PERFETTO_DCHECK(!drop_packets_);
36092 
36093     uint8_t* const wptr = protobuf_stream_writer_.write_ptr();
36094     PERFETTO_DCHECK(wptr >= cur_fragment_start_);
36095     uint32_t partial_size = static_cast<uint32_t>(wptr - cur_fragment_start_);
36096     PERFETTO_DCHECK(partial_size < cur_chunk_.size());
36097 
36098     // Backfill the packet header with the fragment size.
36099     PERFETTO_DCHECK(partial_size > 0);
36100     cur_packet_->inc_size_already_written(partial_size);
36101     cur_chunk_.SetFlag(ChunkHeader::kLastPacketContinuesOnNextChunk);
36102     WriteRedundantVarInt(partial_size, cur_packet_->size_field());
36103 
36104     // Descend in the stack of non-finalized nested submessages (if any) and
36105     // detour their |size_field| into the |patch_list_|. At this point we have
36106     // to release the chunk and they cannot write anymore into that.
36107     // TODO(primiano): add tests to cover this logic.
36108     bool chunk_needs_patching = false;
36109     for (auto* nested_msg = cur_packet_->nested_message(); nested_msg;
36110          nested_msg = nested_msg->nested_message()) {
36111       uint8_t* const cur_hdr = nested_msg->size_field();
36112 
36113       // If this is false the protozero Message has already been instructed to
36114       // write, upon Finalize(), its size into the patch list.
36115       bool size_field_points_within_chunk =
36116           cur_hdr >= cur_chunk_.payload_begin() &&
36117           cur_hdr + kMessageLengthFieldSize <= cur_chunk_.end();
36118 
36119       if (size_field_points_within_chunk) {
36120         auto offset =
36121             static_cast<uint16_t>(cur_hdr - cur_chunk_.payload_begin());
36122         const ChunkID cur_chunk_id =
36123             cur_chunk_.header()->chunk_id.load(std::memory_order_relaxed);
36124         Patch* patch = patch_list_.emplace_back(cur_chunk_id, offset);
36125         nested_msg->set_size_field(&patch->size_field[0]);
36126         chunk_needs_patching = true;
36127       } else {
36128 #if PERFETTO_DCHECK_IS_ON()
36129         // Ensure that the size field of the message points to an element of the
36130         // patch list.
36131         auto patch_it = std::find_if(
36132             patch_list_.begin(), patch_list_.end(),
36133             [cur_hdr](const Patch& p) { return &p.size_field[0] == cur_hdr; });
36134         PERFETTO_DCHECK(patch_it != patch_list_.end());
36135 #endif
36136       }
36137     }  // for(nested_msg
36138 
36139     if (chunk_needs_patching)
36140       cur_chunk_.SetFlag(ChunkHeader::kChunkNeedsPatching);
36141   }  // if(fragmenting_packet)
36142 
36143   if (cur_chunk_.is_valid()) {
36144     // ReturnCompletedChunk will consume the first patched entries from
36145     // |patch_list_| and shrink it.
36146     shmem_arbiter_->ReturnCompletedChunk(std::move(cur_chunk_), target_buffer_,
36147                                          &patch_list_);
36148   }
36149 
36150   // Switch to the new chunk.
36151   drop_packets_ = false;
36152   reached_max_packets_per_chunk_ = false;
36153   retry_new_chunk_after_packet_ = false;
36154   next_chunk_id_++;
36155   cur_chunk_ = std::move(new_chunk);
36156   last_packet_size_field_ = nullptr;
36157 
36158   uint8_t* payload_begin = cur_chunk_.payload_begin();
36159   if (fragmenting_packet_) {
36160     cur_packet_->set_size_field(payload_begin);
36161     last_packet_size_field_ = payload_begin;
36162     memset(payload_begin, 0, kPacketHeaderSize);
36163     payload_begin += kPacketHeaderSize;
36164     cur_fragment_start_ = payload_begin;
36165   }
36166 
36167   return protozero::ContiguousMemoryRange{payload_begin, cur_chunk_.end()};
36168 }
36169 
writer_id() const36170 WriterID TraceWriterImpl::writer_id() const {
36171   return id_;
36172 }
36173 
36174 // Base class definitions.
36175 TraceWriter::TraceWriter() = default;
36176 TraceWriter::~TraceWriter() = default;
36177 
36178 }  // namespace perfetto
36179 // gen_amalgamated begin source: src/tracing/core/virtual_destructors.cc
36180 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/consumer.h
36181 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/observable_events.h
36182 /*
36183  * Copyright (C) 2017 The Android Open Source Project
36184  *
36185  * Licensed under the Apache License, Version 2.0 (the "License");
36186  * you may not use this file except in compliance with the License.
36187  * You may obtain a copy of the License at
36188  *
36189  *      http://www.apache.org/licenses/LICENSE-2.0
36190  *
36191  * Unless required by applicable law or agreed to in writing, software
36192  * distributed under the License is distributed on an "AS IS" BASIS,
36193  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
36194  * See the License for the specific language governing permissions and
36195  * limitations under the License.
36196  */
36197 
36198 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_OBSERVABLE_EVENTS_H_
36199 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_OBSERVABLE_EVENTS_H_
36200 
36201 // Creates the aliases in the ::perfetto namespace, doing things like:
36202 // using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
36203 // See comments in forward_decls.h for the historical reasons of this
36204 // indirection layer.
36205 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
36206 
36207 // gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"
36208 
36209 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_OBSERVABLE_EVENTS_H_
36210 /*
36211  * Copyright (C) 2017 The Android Open Source Project
36212  *
36213  * Licensed under the Apache License, Version 2.0 (the "License");
36214  * you may not use this file except in compliance with the License.
36215  * You may obtain a copy of the License at
36216  *
36217  *      http://www.apache.org/licenses/LICENSE-2.0
36218  *
36219  * Unless required by applicable law or agreed to in writing, software
36220  * distributed under the License is distributed on an "AS IS" BASIS,
36221  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
36222  * See the License for the specific language governing permissions and
36223  * limitations under the License.
36224  */
36225 
36226 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_CONSUMER_H_
36227 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_CONSUMER_H_
36228 
36229 #include <vector>
36230 
36231 // gen_amalgamated expanded: #include "perfetto/base/export.h"
36232 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
36233 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/observable_events.h"
36234 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
36235 namespace perfetto {
36236 
36237 class TracePacket;
36238 
36239 class PERFETTO_EXPORT Consumer {
36240  public:
36241   virtual ~Consumer();
36242 
36243   // Called by Service (or more typically by the transport layer, on behalf of
36244   // the remote Service), once the Consumer <> Service connection has been
36245   // established.
36246   virtual void OnConnect() = 0;
36247 
36248   // Called by the Service or by the transport layer if the connection with the
36249   // service drops, either voluntarily (e.g., by destroying the ConsumerEndpoint
36250   // obtained through Service::ConnectConsumer()) or involuntarily (e.g., if the
36251   // Service process crashes).
36252   virtual void OnDisconnect() = 0;
36253 
36254   // Called by the Service after the tracing session has ended. This can happen
36255   // for a variety of reasons:
36256   // - The consumer explicitly called DisableTracing()
36257   // - The TraceConfig's |duration_ms| has been reached.
36258   // - The TraceConfig's |max_file_size_bytes| has been reached.
36259   // - An error occurred while trying to enable tracing. In this case |error|
36260   //   is non-empty.
36261   virtual void OnTracingDisabled(const std::string& error) = 0;
36262 
36263   // Called back by the Service (or transport layer) after invoking
36264   // TracingService::ConsumerEndpoint::ReadBuffers(). This function can be
36265   // called more than once. Each invocation can carry one or more
36266   // TracePacket(s). Upon the last call, |has_more| is set to true (i.e.
36267   // |has_more| is a !EOF).
36268   virtual void OnTraceData(std::vector<TracePacket>, bool has_more) = 0;
36269 
36270   // Called back by the Service (or transport layer) after invoking
36271   // TracingService::ConsumerEndpoint::Detach().
36272   // The consumer can disconnect at this point and the trace session will keep
36273   // on going. A new consumer can later re-attach passing back the same |key|
36274   // passed to Detach(), but only if the two requests come from the same uid.
36275   virtual void OnDetach(bool success) = 0;
36276 
36277   // Called back by the Service (or transport layer) after invoking
36278   // TracingService::ConsumerEndpoint::Attach().
36279   virtual void OnAttach(bool success, const TraceConfig&) = 0;
36280 
36281   // Called back by the Service (or transport layer) after invoking
36282   // TracingService::ConsumerEndpoint::GetTraceStats().
36283   virtual void OnTraceStats(bool success, const TraceStats&) = 0;
36284 
36285   // Called back by the Service (or transport layer) after invoking
36286   // TracingService::ConsumerEndpoint::ObserveEvents() whenever one or more
36287   // ObservableEvents of enabled event types occur.
36288   virtual void OnObservableEvents(const ObservableEvents&) = 0;
36289 };
36290 
36291 }  // namespace perfetto
36292 
36293 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_CONSUMER_H_
36294 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/producer.h
36295 /*
36296  * Copyright (C) 2017 The Android Open Source Project
36297  *
36298  * Licensed under the Apache License, Version 2.0 (the "License");
36299  * you may not use this file except in compliance with the License.
36300  * You may obtain a copy of the License at
36301  *
36302  *      http://www.apache.org/licenses/LICENSE-2.0
36303  *
36304  * Unless required by applicable law or agreed to in writing, software
36305  * distributed under the License is distributed on an "AS IS" BASIS,
36306  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
36307  * See the License for the specific language governing permissions and
36308  * limitations under the License.
36309  */
36310 
36311 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_PRODUCER_H_
36312 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_PRODUCER_H_
36313 
36314 // gen_amalgamated expanded: #include "perfetto/base/export.h"
36315 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
36316 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
36317 namespace perfetto {
36318 
36319 class SharedMemory;
36320 
36321 // A Producer is an entity that connects to the write-only port of the Service
36322 // and exposes the ability to produce performance data on-demand. The lifecycle
36323 // of a Producer is as follows:
36324 // 1. The producer connects to the service and advertises its data sources
36325 //    (e.g., the ability to get kernel ftraces, to list process stats).
36326 // 2. The service acknowledges the connection and sends over the SharedMemory
36327 //    region that will be used to exchange data (together with the signalling
36328 //    API TracingService::ProducerEndpoint::OnPageAcquired()/OnPageReleased()).
36329 // 3. At some point later on, the Service asks the Producer to turn on some of
36330 //    the previously registered data sources, together with some configuration
36331 //    parameters. This happens via the StartDataSource() callback.
36332 // 4. In response to that the Producer will spawn an instance of the given data
36333 //    source and inject its data into the shared memory buffer (obtained during
36334 //    OnConnect).
36335 // This interface is subclassed by:
36336 //  1. The actual producer code in the clients e.g., the ftrace reader process.
36337 //  2. The transport layer when interposing RPC between service and producers.
36338 class PERFETTO_EXPORT Producer {
36339  public:
36340   virtual ~Producer();
36341 
36342   // Called by Service (or more typically by the transport layer, on behalf of
36343   // the remote Service), once the Producer <> Service connection has been
36344   // established.
36345   virtual void OnConnect() = 0;
36346 
36347   // Called by the Service or by the transport layer if the connection with the
36348   // service drops, either voluntarily (e.g., by destroying the ProducerEndpoint
36349   // obtained through Service::ConnectProducer()) or involuntarily (e.g., if the
36350   // Service process crashes).
36351   // The Producer is expected to tear down all its data sources if this happens.
36352   // Once this call returns it is possible to safely destroy the Producer
36353   // instance.
36354   virtual void OnDisconnect() = 0;
36355 
36356   // Called by the Service after OnConnect but before the first DataSource is
36357   // created. Can be used for any setup required before tracing begins.
36358   virtual void OnTracingSetup() = 0;
36359 
36360   // The lifecycle methods below are always called in the following sequence:
36361   // SetupDataSource  -> StartDataSource -> StopDataSource.
36362   // Or, in the edge case where a trace is aborted immediately:
36363   // SetupDataSource  -> StopDataSource.
36364   // The Setup+Start call sequence is always guaranateed, regardless of the
36365   // TraceConfig.deferred_start flags.
36366   // Called by the Service to configure one of the data sources previously
36367   // registered through TracingService::ProducerEndpoint::RegisterDataSource().
36368   // This method is always called before StartDataSource. There is always a
36369   // SetupDataSource() call before each StartDataSource() call.
36370   // Args:
36371   // - DataSourceInstanceID is an identifier chosen by the Service that should
36372   //   be assigned to the newly created data source instance. It is used to
36373   //   match the StopDataSource() request below.
36374   // - DataSourceConfig is the configuration for the new data source (e.g.,
36375   //   tells which trace categories to enable).
36376   virtual void SetupDataSource(DataSourceInstanceID,
36377                                const DataSourceConfig&) = 0;
36378 
36379   // Called by the Service to turn on one of the data sources previously
36380   // registered through TracingService::ProducerEndpoint::RegisterDataSource()
36381   // and initialized through SetupDataSource().
36382   // Both arguments are guaranteed to be identical to the ones passed to the
36383   // prior SetupDataSource() call.
36384   virtual void StartDataSource(DataSourceInstanceID,
36385                                const DataSourceConfig&) = 0;
36386 
36387   // Called by the Service to shut down an existing data source instance.
36388   virtual void StopDataSource(DataSourceInstanceID) = 0;
36389 
36390   // Called by the service to request the Producer to commit the data of the
36391   // given data sources and return their chunks into the shared memory buffer.
36392   // The Producer is expected to invoke NotifyFlushComplete(FlushRequestID) on
36393   // the Service after the data has been committed. The producer has to either
36394   // reply to the flush requests in order, or can just reply to the latest one
36395   // Upon seeing a NotifyFlushComplete(N), the service will assume that all
36396   // flushes < N have also been committed.
36397   virtual void Flush(FlushRequestID,
36398                      const DataSourceInstanceID* data_source_ids,
36399                      size_t num_data_sources) = 0;
36400 
36401   // Called by the service to instruct the given data sources to stop referring
36402   // to any trace contents emitted so far. The intent is that after processing
36403   // this call, the rest of the trace should be parsable even if all of the
36404   // packets emitted so far have been lost (for example due to ring buffer
36405   // overwrites).
36406   //
36407   // Called only for Producers with active data sources that have opted in by
36408   // setting |handles_incremental_state_clear| in their DataSourceDescriptor.
36409   //
36410   // The way this call is handled is up to the individual Producer
36411   // implementation. Some might wish to emit invalidation markers in the trace
36412   // (see TracePacket.incremental_state_cleared for an existing field), and
36413   // handle them when parsing the trace.
36414   virtual void ClearIncrementalState(
36415       const DataSourceInstanceID* data_source_ids,
36416       size_t num_data_sources) = 0;
36417 };
36418 
36419 }  // namespace perfetto
36420 
36421 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_PRODUCER_H_
36422 /*
36423  * Copyright (C) 2018 The Android Open Source Project
36424  *
36425  * Licensed under the Apache License, Version 2.0 (the "License");
36426  * you may not use this file except in compliance with the License.
36427  * You may obtain a copy of the License at
36428  *
36429  *      http://www.apache.org/licenses/LICENSE-2.0
36430  *
36431  * Unless required by applicable law or agreed to in writing, software
36432  * distributed under the License is distributed on an "AS IS" BASIS,
36433  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
36434  * See the License for the specific language governing permissions and
36435  * limitations under the License.
36436  */
36437 
36438 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
36439 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
36440 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
36441 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
36442 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
36443 
36444 // This translation unit contains the definitions for the destructor of pure
36445 // virtual interfaces for the current build target. The alternative would be
36446 // introducing a one-liner .cc file for each pure virtual interface, which is
36447 // overkill. This is for compliance with -Wweak-vtables.
36448 
36449 namespace perfetto {
36450 
36451 Consumer::~Consumer() = default;
36452 Producer::~Producer() = default;
36453 TracingService::~TracingService() = default;
36454 ConsumerEndpoint::~ConsumerEndpoint() = default;
36455 ProducerEndpoint::~ProducerEndpoint() = default;
36456 SharedMemory::~SharedMemory() = default;
36457 SharedMemory::Factory::~Factory() = default;
36458 SharedMemoryArbiter::~SharedMemoryArbiter() = default;
36459 
36460 }  // namespace perfetto
36461 // gen_amalgamated begin source: src/tracing/console_interceptor.cc
36462 // gen_amalgamated begin header: gen/protos/perfetto/config/interceptors/console_config.pbzero.h
36463 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
36464 
36465 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTORS_CONSOLE_CONFIG_PROTO_H_
36466 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTORS_CONSOLE_CONFIG_PROTO_H_
36467 
36468 #include <stddef.h>
36469 #include <stdint.h>
36470 
36471 // gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
36472 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
36473 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
36474 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
36475 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
36476 
36477 namespace perfetto {
36478 namespace protos {
36479 namespace pbzero {
36480 
36481 enum ConsoleConfig_Output : int32_t;
36482 
36483 enum ConsoleConfig_Output : int32_t {
36484   ConsoleConfig_Output_OUTPUT_UNSPECIFIED = 0,
36485   ConsoleConfig_Output_OUTPUT_STDOUT = 1,
36486   ConsoleConfig_Output_OUTPUT_STDERR = 2,
36487 };
36488 
36489 const ConsoleConfig_Output ConsoleConfig_Output_MIN = ConsoleConfig_Output_OUTPUT_UNSPECIFIED;
36490 const ConsoleConfig_Output ConsoleConfig_Output_MAX = ConsoleConfig_Output_OUTPUT_STDERR;
36491 
36492 class ConsoleConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
36493  public:
ConsoleConfig_Decoder(const uint8_t * data,size_t len)36494   ConsoleConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
ConsoleConfig_Decoder(const std::string & raw)36495   explicit ConsoleConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
ConsoleConfig_Decoder(const::protozero::ConstBytes & raw)36496   explicit ConsoleConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_output() const36497   bool has_output() const { return at<1>().valid(); }
output() const36498   int32_t output() const { return at<1>().as_int32(); }
has_enable_colors() const36499   bool has_enable_colors() const { return at<2>().valid(); }
enable_colors() const36500   bool enable_colors() const { return at<2>().as_bool(); }
36501 };
36502 
36503 class ConsoleConfig : public ::protozero::Message {
36504  public:
36505   using Decoder = ConsoleConfig_Decoder;
36506   enum : int32_t {
36507     kOutputFieldNumber = 1,
36508     kEnableColorsFieldNumber = 2,
36509   };
36510   using Output = ::perfetto::protos::pbzero::ConsoleConfig_Output;
36511   static const Output OUTPUT_UNSPECIFIED = ConsoleConfig_Output_OUTPUT_UNSPECIFIED;
36512   static const Output OUTPUT_STDOUT = ConsoleConfig_Output_OUTPUT_STDOUT;
36513   static const Output OUTPUT_STDERR = ConsoleConfig_Output_OUTPUT_STDERR;
36514 
36515   using FieldMetadata_Output =
36516     ::protozero::proto_utils::FieldMetadata<
36517       1,
36518       ::protozero::proto_utils::RepetitionType::kNotRepeated,
36519       ::protozero::proto_utils::ProtoSchemaType::kEnum,
36520       ::perfetto::protos::pbzero::ConsoleConfig_Output,
36521       ConsoleConfig>;
36522 
36523   // Ceci n'est pas une pipe.
36524   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
36525   // type (and users are expected to use it as such, hence kCamelCase name).
36526   // It is declared as a function to keep protozero bindings header-only as
36527   // inline constexpr variables are not available until C++17 (while inline
36528   // functions are).
36529   // TODO(altimin): Use inline variable instead after adopting C++17.
kOutput()36530   static constexpr FieldMetadata_Output kOutput() { return {}; }
set_output(::perfetto::protos::pbzero::ConsoleConfig_Output value)36531   void set_output(::perfetto::protos::pbzero::ConsoleConfig_Output value) {
36532     static constexpr uint32_t field_id = FieldMetadata_Output::kFieldId;
36533     // Call the appropriate protozero::Message::Append(field_id, ...)
36534     // method based on the type of the field.
36535     ::protozero::internal::FieldWriter<
36536       ::protozero::proto_utils::ProtoSchemaType::kEnum>
36537         ::Append(*this, field_id, value);
36538   }
36539 
36540   using FieldMetadata_EnableColors =
36541     ::protozero::proto_utils::FieldMetadata<
36542       2,
36543       ::protozero::proto_utils::RepetitionType::kNotRepeated,
36544       ::protozero::proto_utils::ProtoSchemaType::kBool,
36545       bool,
36546       ConsoleConfig>;
36547 
36548   // Ceci n'est pas une pipe.
36549   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
36550   // type (and users are expected to use it as such, hence kCamelCase name).
36551   // It is declared as a function to keep protozero bindings header-only as
36552   // inline constexpr variables are not available until C++17 (while inline
36553   // functions are).
36554   // TODO(altimin): Use inline variable instead after adopting C++17.
kEnableColors()36555   static constexpr FieldMetadata_EnableColors kEnableColors() { return {}; }
set_enable_colors(bool value)36556   void set_enable_colors(bool value) {
36557     static constexpr uint32_t field_id = FieldMetadata_EnableColors::kFieldId;
36558     // Call the appropriate protozero::Message::Append(field_id, ...)
36559     // method based on the type of the field.
36560     ::protozero::internal::FieldWriter<
36561       ::protozero::proto_utils::ProtoSchemaType::kBool>
36562         ::Append(*this, field_id, value);
36563   }
36564 };
36565 
36566 } // Namespace.
36567 } // Namespace.
36568 } // Namespace.
36569 #endif  // Include guard.
36570 // gen_amalgamated begin header: gen/protos/perfetto/trace/trace_packet_defaults.pbzero.h
36571 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
36572 
36573 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACE_PACKET_DEFAULTS_PROTO_H_
36574 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACE_PACKET_DEFAULTS_PROTO_H_
36575 
36576 #include <stddef.h>
36577 #include <stdint.h>
36578 
36579 // gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
36580 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
36581 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
36582 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
36583 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
36584 
36585 namespace perfetto {
36586 namespace protos {
36587 namespace pbzero {
36588 
36589 class PerfSampleDefaults;
36590 class TrackEventDefaults;
36591 
36592 class TracePacketDefaults_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/58, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
36593  public:
TracePacketDefaults_Decoder(const uint8_t * data,size_t len)36594   TracePacketDefaults_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TracePacketDefaults_Decoder(const std::string & raw)36595   explicit TracePacketDefaults_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
TracePacketDefaults_Decoder(const::protozero::ConstBytes & raw)36596   explicit TracePacketDefaults_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_timestamp_clock_id() const36597   bool has_timestamp_clock_id() const { return at<58>().valid(); }
timestamp_clock_id() const36598   uint32_t timestamp_clock_id() const { return at<58>().as_uint32(); }
has_track_event_defaults() const36599   bool has_track_event_defaults() const { return at<11>().valid(); }
track_event_defaults() const36600   ::protozero::ConstBytes track_event_defaults() const { return at<11>().as_bytes(); }
has_perf_sample_defaults() const36601   bool has_perf_sample_defaults() const { return at<12>().valid(); }
perf_sample_defaults() const36602   ::protozero::ConstBytes perf_sample_defaults() const { return at<12>().as_bytes(); }
36603 };
36604 
36605 class TracePacketDefaults : public ::protozero::Message {
36606  public:
36607   using Decoder = TracePacketDefaults_Decoder;
36608   enum : int32_t {
36609     kTimestampClockIdFieldNumber = 58,
36610     kTrackEventDefaultsFieldNumber = 11,
36611     kPerfSampleDefaultsFieldNumber = 12,
36612   };
36613 
36614   using FieldMetadata_TimestampClockId =
36615     ::protozero::proto_utils::FieldMetadata<
36616       58,
36617       ::protozero::proto_utils::RepetitionType::kNotRepeated,
36618       ::protozero::proto_utils::ProtoSchemaType::kUint32,
36619       uint32_t,
36620       TracePacketDefaults>;
36621 
36622   // Ceci n'est pas une pipe.
36623   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
36624   // type (and users are expected to use it as such, hence kCamelCase name).
36625   // It is declared as a function to keep protozero bindings header-only as
36626   // inline constexpr variables are not available until C++17 (while inline
36627   // functions are).
36628   // TODO(altimin): Use inline variable instead after adopting C++17.
kTimestampClockId()36629   static constexpr FieldMetadata_TimestampClockId kTimestampClockId() { return {}; }
set_timestamp_clock_id(uint32_t value)36630   void set_timestamp_clock_id(uint32_t value) {
36631     static constexpr uint32_t field_id = FieldMetadata_TimestampClockId::kFieldId;
36632     // Call the appropriate protozero::Message::Append(field_id, ...)
36633     // method based on the type of the field.
36634     ::protozero::internal::FieldWriter<
36635       ::protozero::proto_utils::ProtoSchemaType::kUint32>
36636         ::Append(*this, field_id, value);
36637   }
36638 
36639   using FieldMetadata_TrackEventDefaults =
36640     ::protozero::proto_utils::FieldMetadata<
36641       11,
36642       ::protozero::proto_utils::RepetitionType::kNotRepeated,
36643       ::protozero::proto_utils::ProtoSchemaType::kMessage,
36644       TrackEventDefaults,
36645       TracePacketDefaults>;
36646 
36647   // Ceci n'est pas une pipe.
36648   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
36649   // type (and users are expected to use it as such, hence kCamelCase name).
36650   // It is declared as a function to keep protozero bindings header-only as
36651   // inline constexpr variables are not available until C++17 (while inline
36652   // functions are).
36653   // TODO(altimin): Use inline variable instead after adopting C++17.
kTrackEventDefaults()36654   static constexpr FieldMetadata_TrackEventDefaults kTrackEventDefaults() { return {}; }
set_track_event_defaults()36655   template <typename T = TrackEventDefaults> T* set_track_event_defaults() {
36656     return BeginNestedMessage<T>(11);
36657   }
36658 
36659 
36660   using FieldMetadata_PerfSampleDefaults =
36661     ::protozero::proto_utils::FieldMetadata<
36662       12,
36663       ::protozero::proto_utils::RepetitionType::kNotRepeated,
36664       ::protozero::proto_utils::ProtoSchemaType::kMessage,
36665       PerfSampleDefaults,
36666       TracePacketDefaults>;
36667 
36668   // Ceci n'est pas une pipe.
36669   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
36670   // type (and users are expected to use it as such, hence kCamelCase name).
36671   // It is declared as a function to keep protozero bindings header-only as
36672   // inline constexpr variables are not available until C++17 (while inline
36673   // functions are).
36674   // TODO(altimin): Use inline variable instead after adopting C++17.
kPerfSampleDefaults()36675   static constexpr FieldMetadata_PerfSampleDefaults kPerfSampleDefaults() { return {}; }
set_perf_sample_defaults()36676   template <typename T = PerfSampleDefaults> T* set_perf_sample_defaults() {
36677     return BeginNestedMessage<T>(12);
36678   }
36679 
36680 };
36681 
36682 } // Namespace.
36683 } // Namespace.
36684 } // Namespace.
36685 #endif  // Include guard.
36686 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/process_descriptor.pbzero.h
36687 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
36688 
36689 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_PROCESS_DESCRIPTOR_PROTO_H_
36690 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_PROCESS_DESCRIPTOR_PROTO_H_
36691 
36692 #include <stddef.h>
36693 #include <stdint.h>
36694 
36695 // gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
36696 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
36697 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
36698 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
36699 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
36700 
36701 namespace perfetto {
36702 namespace protos {
36703 namespace pbzero {
36704 
36705 enum ProcessDescriptor_ChromeProcessType : int32_t;
36706 
36707 enum ProcessDescriptor_ChromeProcessType : int32_t {
36708   ProcessDescriptor_ChromeProcessType_PROCESS_UNSPECIFIED = 0,
36709   ProcessDescriptor_ChromeProcessType_PROCESS_BROWSER = 1,
36710   ProcessDescriptor_ChromeProcessType_PROCESS_RENDERER = 2,
36711   ProcessDescriptor_ChromeProcessType_PROCESS_UTILITY = 3,
36712   ProcessDescriptor_ChromeProcessType_PROCESS_ZYGOTE = 4,
36713   ProcessDescriptor_ChromeProcessType_PROCESS_SANDBOX_HELPER = 5,
36714   ProcessDescriptor_ChromeProcessType_PROCESS_GPU = 6,
36715   ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_PLUGIN = 7,
36716   ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_BROKER = 8,
36717 };
36718 
36719 const ProcessDescriptor_ChromeProcessType ProcessDescriptor_ChromeProcessType_MIN = ProcessDescriptor_ChromeProcessType_PROCESS_UNSPECIFIED;
36720 const ProcessDescriptor_ChromeProcessType ProcessDescriptor_ChromeProcessType_MAX = ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_BROKER;
36721 
36722 class ProcessDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
36723  public:
ProcessDescriptor_Decoder(const uint8_t * data,size_t len)36724   ProcessDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
ProcessDescriptor_Decoder(const std::string & raw)36725   explicit ProcessDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
ProcessDescriptor_Decoder(const::protozero::ConstBytes & raw)36726   explicit ProcessDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_pid() const36727   bool has_pid() const { return at<1>().valid(); }
pid() const36728   int32_t pid() const { return at<1>().as_int32(); }
has_cmdline() const36729   bool has_cmdline() const { return at<2>().valid(); }
cmdline() const36730   ::protozero::RepeatedFieldIterator<::protozero::ConstChars> cmdline() const { return GetRepeated<::protozero::ConstChars>(2); }
has_process_name() const36731   bool has_process_name() const { return at<6>().valid(); }
process_name() const36732   ::protozero::ConstChars process_name() const { return at<6>().as_string(); }
has_process_priority() const36733   bool has_process_priority() const { return at<5>().valid(); }
process_priority() const36734   int32_t process_priority() const { return at<5>().as_int32(); }
has_start_timestamp_ns() const36735   bool has_start_timestamp_ns() const { return at<7>().valid(); }
start_timestamp_ns() const36736   int64_t start_timestamp_ns() const { return at<7>().as_int64(); }
has_chrome_process_type() const36737   bool has_chrome_process_type() const { return at<4>().valid(); }
chrome_process_type() const36738   int32_t chrome_process_type() const { return at<4>().as_int32(); }
has_legacy_sort_index() const36739   bool has_legacy_sort_index() const { return at<3>().valid(); }
legacy_sort_index() const36740   int32_t legacy_sort_index() const { return at<3>().as_int32(); }
36741 };
36742 
36743 class ProcessDescriptor : public ::protozero::Message {
36744  public:
36745   using Decoder = ProcessDescriptor_Decoder;
36746   enum : int32_t {
36747     kPidFieldNumber = 1,
36748     kCmdlineFieldNumber = 2,
36749     kProcessNameFieldNumber = 6,
36750     kProcessPriorityFieldNumber = 5,
36751     kStartTimestampNsFieldNumber = 7,
36752     kChromeProcessTypeFieldNumber = 4,
36753     kLegacySortIndexFieldNumber = 3,
36754   };
36755   using ChromeProcessType = ::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType;
36756   static const ChromeProcessType PROCESS_UNSPECIFIED = ProcessDescriptor_ChromeProcessType_PROCESS_UNSPECIFIED;
36757   static const ChromeProcessType PROCESS_BROWSER = ProcessDescriptor_ChromeProcessType_PROCESS_BROWSER;
36758   static const ChromeProcessType PROCESS_RENDERER = ProcessDescriptor_ChromeProcessType_PROCESS_RENDERER;
36759   static const ChromeProcessType PROCESS_UTILITY = ProcessDescriptor_ChromeProcessType_PROCESS_UTILITY;
36760   static const ChromeProcessType PROCESS_ZYGOTE = ProcessDescriptor_ChromeProcessType_PROCESS_ZYGOTE;
36761   static const ChromeProcessType PROCESS_SANDBOX_HELPER = ProcessDescriptor_ChromeProcessType_PROCESS_SANDBOX_HELPER;
36762   static const ChromeProcessType PROCESS_GPU = ProcessDescriptor_ChromeProcessType_PROCESS_GPU;
36763   static const ChromeProcessType PROCESS_PPAPI_PLUGIN = ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_PLUGIN;
36764   static const ChromeProcessType PROCESS_PPAPI_BROKER = ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_BROKER;
36765 
36766   using FieldMetadata_Pid =
36767     ::protozero::proto_utils::FieldMetadata<
36768       1,
36769       ::protozero::proto_utils::RepetitionType::kNotRepeated,
36770       ::protozero::proto_utils::ProtoSchemaType::kInt32,
36771       int32_t,
36772       ProcessDescriptor>;
36773 
36774   // Ceci n'est pas une pipe.
36775   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
36776   // type (and users are expected to use it as such, hence kCamelCase name).
36777   // It is declared as a function to keep protozero bindings header-only as
36778   // inline constexpr variables are not available until C++17 (while inline
36779   // functions are).
36780   // TODO(altimin): Use inline variable instead after adopting C++17.
kPid()36781   static constexpr FieldMetadata_Pid kPid() { return {}; }
set_pid(int32_t value)36782   void set_pid(int32_t value) {
36783     static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
36784     // Call the appropriate protozero::Message::Append(field_id, ...)
36785     // method based on the type of the field.
36786     ::protozero::internal::FieldWriter<
36787       ::protozero::proto_utils::ProtoSchemaType::kInt32>
36788         ::Append(*this, field_id, value);
36789   }
36790 
36791   using FieldMetadata_Cmdline =
36792     ::protozero::proto_utils::FieldMetadata<
36793       2,
36794       ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
36795       ::protozero::proto_utils::ProtoSchemaType::kString,
36796       std::string,
36797       ProcessDescriptor>;
36798 
36799   // Ceci n'est pas une pipe.
36800   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
36801   // type (and users are expected to use it as such, hence kCamelCase name).
36802   // It is declared as a function to keep protozero bindings header-only as
36803   // inline constexpr variables are not available until C++17 (while inline
36804   // functions are).
36805   // TODO(altimin): Use inline variable instead after adopting C++17.
kCmdline()36806   static constexpr FieldMetadata_Cmdline kCmdline() { return {}; }
add_cmdline(const char * data,size_t size)36807   void add_cmdline(const char* data, size_t size) {
36808     AppendBytes(FieldMetadata_Cmdline::kFieldId, data, size);
36809   }
add_cmdline(std::string value)36810   void add_cmdline(std::string value) {
36811     static constexpr uint32_t field_id = FieldMetadata_Cmdline::kFieldId;
36812     // Call the appropriate protozero::Message::Append(field_id, ...)
36813     // method based on the type of the field.
36814     ::protozero::internal::FieldWriter<
36815       ::protozero::proto_utils::ProtoSchemaType::kString>
36816         ::Append(*this, field_id, value);
36817   }
36818 
36819   using FieldMetadata_ProcessName =
36820     ::protozero::proto_utils::FieldMetadata<
36821       6,
36822       ::protozero::proto_utils::RepetitionType::kNotRepeated,
36823       ::protozero::proto_utils::ProtoSchemaType::kString,
36824       std::string,
36825       ProcessDescriptor>;
36826 
36827   // Ceci n'est pas une pipe.
36828   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
36829   // type (and users are expected to use it as such, hence kCamelCase name).
36830   // It is declared as a function to keep protozero bindings header-only as
36831   // inline constexpr variables are not available until C++17 (while inline
36832   // functions are).
36833   // TODO(altimin): Use inline variable instead after adopting C++17.
kProcessName()36834   static constexpr FieldMetadata_ProcessName kProcessName() { return {}; }
set_process_name(const char * data,size_t size)36835   void set_process_name(const char* data, size_t size) {
36836     AppendBytes(FieldMetadata_ProcessName::kFieldId, data, size);
36837   }
set_process_name(std::string value)36838   void set_process_name(std::string value) {
36839     static constexpr uint32_t field_id = FieldMetadata_ProcessName::kFieldId;
36840     // Call the appropriate protozero::Message::Append(field_id, ...)
36841     // method based on the type of the field.
36842     ::protozero::internal::FieldWriter<
36843       ::protozero::proto_utils::ProtoSchemaType::kString>
36844         ::Append(*this, field_id, value);
36845   }
36846 
36847   using FieldMetadata_ProcessPriority =
36848     ::protozero::proto_utils::FieldMetadata<
36849       5,
36850       ::protozero::proto_utils::RepetitionType::kNotRepeated,
36851       ::protozero::proto_utils::ProtoSchemaType::kInt32,
36852       int32_t,
36853       ProcessDescriptor>;
36854 
36855   // Ceci n'est pas une pipe.
36856   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
36857   // type (and users are expected to use it as such, hence kCamelCase name).
36858   // It is declared as a function to keep protozero bindings header-only as
36859   // inline constexpr variables are not available until C++17 (while inline
36860   // functions are).
36861   // TODO(altimin): Use inline variable instead after adopting C++17.
kProcessPriority()36862   static constexpr FieldMetadata_ProcessPriority kProcessPriority() { return {}; }
set_process_priority(int32_t value)36863   void set_process_priority(int32_t value) {
36864     static constexpr uint32_t field_id = FieldMetadata_ProcessPriority::kFieldId;
36865     // Call the appropriate protozero::Message::Append(field_id, ...)
36866     // method based on the type of the field.
36867     ::protozero::internal::FieldWriter<
36868       ::protozero::proto_utils::ProtoSchemaType::kInt32>
36869         ::Append(*this, field_id, value);
36870   }
36871 
36872   using FieldMetadata_StartTimestampNs =
36873     ::protozero::proto_utils::FieldMetadata<
36874       7,
36875       ::protozero::proto_utils::RepetitionType::kNotRepeated,
36876       ::protozero::proto_utils::ProtoSchemaType::kInt64,
36877       int64_t,
36878       ProcessDescriptor>;
36879 
36880   // Ceci n'est pas une pipe.
36881   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
36882   // type (and users are expected to use it as such, hence kCamelCase name).
36883   // It is declared as a function to keep protozero bindings header-only as
36884   // inline constexpr variables are not available until C++17 (while inline
36885   // functions are).
36886   // TODO(altimin): Use inline variable instead after adopting C++17.
kStartTimestampNs()36887   static constexpr FieldMetadata_StartTimestampNs kStartTimestampNs() { return {}; }
set_start_timestamp_ns(int64_t value)36888   void set_start_timestamp_ns(int64_t value) {
36889     static constexpr uint32_t field_id = FieldMetadata_StartTimestampNs::kFieldId;
36890     // Call the appropriate protozero::Message::Append(field_id, ...)
36891     // method based on the type of the field.
36892     ::protozero::internal::FieldWriter<
36893       ::protozero::proto_utils::ProtoSchemaType::kInt64>
36894         ::Append(*this, field_id, value);
36895   }
36896 
36897   using FieldMetadata_ChromeProcessType =
36898     ::protozero::proto_utils::FieldMetadata<
36899       4,
36900       ::protozero::proto_utils::RepetitionType::kNotRepeated,
36901       ::protozero::proto_utils::ProtoSchemaType::kEnum,
36902       ::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType,
36903       ProcessDescriptor>;
36904 
36905   // Ceci n'est pas une pipe.
36906   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
36907   // type (and users are expected to use it as such, hence kCamelCase name).
36908   // It is declared as a function to keep protozero bindings header-only as
36909   // inline constexpr variables are not available until C++17 (while inline
36910   // functions are).
36911   // TODO(altimin): Use inline variable instead after adopting C++17.
kChromeProcessType()36912   static constexpr FieldMetadata_ChromeProcessType kChromeProcessType() { return {}; }
set_chrome_process_type(::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType value)36913   void set_chrome_process_type(::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType value) {
36914     static constexpr uint32_t field_id = FieldMetadata_ChromeProcessType::kFieldId;
36915     // Call the appropriate protozero::Message::Append(field_id, ...)
36916     // method based on the type of the field.
36917     ::protozero::internal::FieldWriter<
36918       ::protozero::proto_utils::ProtoSchemaType::kEnum>
36919         ::Append(*this, field_id, value);
36920   }
36921 
36922   using FieldMetadata_LegacySortIndex =
36923     ::protozero::proto_utils::FieldMetadata<
36924       3,
36925       ::protozero::proto_utils::RepetitionType::kNotRepeated,
36926       ::protozero::proto_utils::ProtoSchemaType::kInt32,
36927       int32_t,
36928       ProcessDescriptor>;
36929 
36930   // Ceci n'est pas une pipe.
36931   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
36932   // type (and users are expected to use it as such, hence kCamelCase name).
36933   // It is declared as a function to keep protozero bindings header-only as
36934   // inline constexpr variables are not available until C++17 (while inline
36935   // functions are).
36936   // TODO(altimin): Use inline variable instead after adopting C++17.
kLegacySortIndex()36937   static constexpr FieldMetadata_LegacySortIndex kLegacySortIndex() { return {}; }
set_legacy_sort_index(int32_t value)36938   void set_legacy_sort_index(int32_t value) {
36939     static constexpr uint32_t field_id = FieldMetadata_LegacySortIndex::kFieldId;
36940     // Call the appropriate protozero::Message::Append(field_id, ...)
36941     // method based on the type of the field.
36942     ::protozero::internal::FieldWriter<
36943       ::protozero::proto_utils::ProtoSchemaType::kInt32>
36944         ::Append(*this, field_id, value);
36945   }
36946 };
36947 
36948 } // Namespace.
36949 } // Namespace.
36950 } // Namespace.
36951 #endif  // Include guard.
36952 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/thread_descriptor.pbzero.h
36953 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
36954 
36955 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_THREAD_DESCRIPTOR_PROTO_H_
36956 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_THREAD_DESCRIPTOR_PROTO_H_
36957 
36958 #include <stddef.h>
36959 #include <stdint.h>
36960 
36961 // gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
36962 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
36963 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
36964 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
36965 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
36966 
36967 namespace perfetto {
36968 namespace protos {
36969 namespace pbzero {
36970 
36971 enum ThreadDescriptor_ChromeThreadType : int32_t;
36972 
36973 enum ThreadDescriptor_ChromeThreadType : int32_t {
36974   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_UNSPECIFIED = 0,
36975   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MAIN = 1,
36976   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_IO = 2,
36977   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_WORKER = 3,
36978   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FG_WORKER = 4,
36979   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FB_BLOCKING = 5,
36980   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_BLOCKING = 6,
36981   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_SERVICE = 7,
36982   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR = 8,
36983   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_VIZ_COMPOSITOR = 9,
36984   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR_WORKER = 10,
36985   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SERVICE_WORKER = 11,
36986   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MEMORY_INFRA = 50,
36987   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SAMPLING_PROFILER = 51,
36988 };
36989 
36990 const ThreadDescriptor_ChromeThreadType ThreadDescriptor_ChromeThreadType_MIN = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_UNSPECIFIED;
36991 const ThreadDescriptor_ChromeThreadType ThreadDescriptor_ChromeThreadType_MAX = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SAMPLING_PROFILER;
36992 
36993 class ThreadDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
36994  public:
ThreadDescriptor_Decoder(const uint8_t * data,size_t len)36995   ThreadDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
ThreadDescriptor_Decoder(const std::string & raw)36996   explicit ThreadDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
ThreadDescriptor_Decoder(const::protozero::ConstBytes & raw)36997   explicit ThreadDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_pid() const36998   bool has_pid() const { return at<1>().valid(); }
pid() const36999   int32_t pid() const { return at<1>().as_int32(); }
has_tid() const37000   bool has_tid() const { return at<2>().valid(); }
tid() const37001   int32_t tid() const { return at<2>().as_int32(); }
has_thread_name() const37002   bool has_thread_name() const { return at<5>().valid(); }
thread_name() const37003   ::protozero::ConstChars thread_name() const { return at<5>().as_string(); }
has_chrome_thread_type() const37004   bool has_chrome_thread_type() const { return at<4>().valid(); }
chrome_thread_type() const37005   int32_t chrome_thread_type() const { return at<4>().as_int32(); }
has_reference_timestamp_us() const37006   bool has_reference_timestamp_us() const { return at<6>().valid(); }
reference_timestamp_us() const37007   int64_t reference_timestamp_us() const { return at<6>().as_int64(); }
has_reference_thread_time_us() const37008   bool has_reference_thread_time_us() const { return at<7>().valid(); }
reference_thread_time_us() const37009   int64_t reference_thread_time_us() const { return at<7>().as_int64(); }
has_reference_thread_instruction_count() const37010   bool has_reference_thread_instruction_count() const { return at<8>().valid(); }
reference_thread_instruction_count() const37011   int64_t reference_thread_instruction_count() const { return at<8>().as_int64(); }
has_legacy_sort_index() const37012   bool has_legacy_sort_index() const { return at<3>().valid(); }
legacy_sort_index() const37013   int32_t legacy_sort_index() const { return at<3>().as_int32(); }
37014 };
37015 
37016 class ThreadDescriptor : public ::protozero::Message {
37017  public:
37018   using Decoder = ThreadDescriptor_Decoder;
37019   enum : int32_t {
37020     kPidFieldNumber = 1,
37021     kTidFieldNumber = 2,
37022     kThreadNameFieldNumber = 5,
37023     kChromeThreadTypeFieldNumber = 4,
37024     kReferenceTimestampUsFieldNumber = 6,
37025     kReferenceThreadTimeUsFieldNumber = 7,
37026     kReferenceThreadInstructionCountFieldNumber = 8,
37027     kLegacySortIndexFieldNumber = 3,
37028   };
37029   using ChromeThreadType = ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType;
37030   static const ChromeThreadType CHROME_THREAD_UNSPECIFIED = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_UNSPECIFIED;
37031   static const ChromeThreadType CHROME_THREAD_MAIN = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MAIN;
37032   static const ChromeThreadType CHROME_THREAD_IO = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_IO;
37033   static const ChromeThreadType CHROME_THREAD_POOL_BG_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_WORKER;
37034   static const ChromeThreadType CHROME_THREAD_POOL_FG_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FG_WORKER;
37035   static const ChromeThreadType CHROME_THREAD_POOL_FB_BLOCKING = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FB_BLOCKING;
37036   static const ChromeThreadType CHROME_THREAD_POOL_BG_BLOCKING = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_BLOCKING;
37037   static const ChromeThreadType CHROME_THREAD_POOL_SERVICE = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_SERVICE;
37038   static const ChromeThreadType CHROME_THREAD_COMPOSITOR = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR;
37039   static const ChromeThreadType CHROME_THREAD_VIZ_COMPOSITOR = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_VIZ_COMPOSITOR;
37040   static const ChromeThreadType CHROME_THREAD_COMPOSITOR_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR_WORKER;
37041   static const ChromeThreadType CHROME_THREAD_SERVICE_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SERVICE_WORKER;
37042   static const ChromeThreadType CHROME_THREAD_MEMORY_INFRA = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MEMORY_INFRA;
37043   static const ChromeThreadType CHROME_THREAD_SAMPLING_PROFILER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SAMPLING_PROFILER;
37044 
37045   using FieldMetadata_Pid =
37046     ::protozero::proto_utils::FieldMetadata<
37047       1,
37048       ::protozero::proto_utils::RepetitionType::kNotRepeated,
37049       ::protozero::proto_utils::ProtoSchemaType::kInt32,
37050       int32_t,
37051       ThreadDescriptor>;
37052 
37053   // Ceci n'est pas une pipe.
37054   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
37055   // type (and users are expected to use it as such, hence kCamelCase name).
37056   // It is declared as a function to keep protozero bindings header-only as
37057   // inline constexpr variables are not available until C++17 (while inline
37058   // functions are).
37059   // TODO(altimin): Use inline variable instead after adopting C++17.
kPid()37060   static constexpr FieldMetadata_Pid kPid() { return {}; }
set_pid(int32_t value)37061   void set_pid(int32_t value) {
37062     static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
37063     // Call the appropriate protozero::Message::Append(field_id, ...)
37064     // method based on the type of the field.
37065     ::protozero::internal::FieldWriter<
37066       ::protozero::proto_utils::ProtoSchemaType::kInt32>
37067         ::Append(*this, field_id, value);
37068   }
37069 
37070   using FieldMetadata_Tid =
37071     ::protozero::proto_utils::FieldMetadata<
37072       2,
37073       ::protozero::proto_utils::RepetitionType::kNotRepeated,
37074       ::protozero::proto_utils::ProtoSchemaType::kInt32,
37075       int32_t,
37076       ThreadDescriptor>;
37077 
37078   // Ceci n'est pas une pipe.
37079   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
37080   // type (and users are expected to use it as such, hence kCamelCase name).
37081   // It is declared as a function to keep protozero bindings header-only as
37082   // inline constexpr variables are not available until C++17 (while inline
37083   // functions are).
37084   // TODO(altimin): Use inline variable instead after adopting C++17.
kTid()37085   static constexpr FieldMetadata_Tid kTid() { return {}; }
set_tid(int32_t value)37086   void set_tid(int32_t value) {
37087     static constexpr uint32_t field_id = FieldMetadata_Tid::kFieldId;
37088     // Call the appropriate protozero::Message::Append(field_id, ...)
37089     // method based on the type of the field.
37090     ::protozero::internal::FieldWriter<
37091       ::protozero::proto_utils::ProtoSchemaType::kInt32>
37092         ::Append(*this, field_id, value);
37093   }
37094 
37095   using FieldMetadata_ThreadName =
37096     ::protozero::proto_utils::FieldMetadata<
37097       5,
37098       ::protozero::proto_utils::RepetitionType::kNotRepeated,
37099       ::protozero::proto_utils::ProtoSchemaType::kString,
37100       std::string,
37101       ThreadDescriptor>;
37102 
37103   // Ceci n'est pas une pipe.
37104   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
37105   // type (and users are expected to use it as such, hence kCamelCase name).
37106   // It is declared as a function to keep protozero bindings header-only as
37107   // inline constexpr variables are not available until C++17 (while inline
37108   // functions are).
37109   // TODO(altimin): Use inline variable instead after adopting C++17.
kThreadName()37110   static constexpr FieldMetadata_ThreadName kThreadName() { return {}; }
set_thread_name(const char * data,size_t size)37111   void set_thread_name(const char* data, size_t size) {
37112     AppendBytes(FieldMetadata_ThreadName::kFieldId, data, size);
37113   }
set_thread_name(std::string value)37114   void set_thread_name(std::string value) {
37115     static constexpr uint32_t field_id = FieldMetadata_ThreadName::kFieldId;
37116     // Call the appropriate protozero::Message::Append(field_id, ...)
37117     // method based on the type of the field.
37118     ::protozero::internal::FieldWriter<
37119       ::protozero::proto_utils::ProtoSchemaType::kString>
37120         ::Append(*this, field_id, value);
37121   }
37122 
37123   using FieldMetadata_ChromeThreadType =
37124     ::protozero::proto_utils::FieldMetadata<
37125       4,
37126       ::protozero::proto_utils::RepetitionType::kNotRepeated,
37127       ::protozero::proto_utils::ProtoSchemaType::kEnum,
37128       ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType,
37129       ThreadDescriptor>;
37130 
37131   // Ceci n'est pas une pipe.
37132   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
37133   // type (and users are expected to use it as such, hence kCamelCase name).
37134   // It is declared as a function to keep protozero bindings header-only as
37135   // inline constexpr variables are not available until C++17 (while inline
37136   // functions are).
37137   // TODO(altimin): Use inline variable instead after adopting C++17.
kChromeThreadType()37138   static constexpr FieldMetadata_ChromeThreadType kChromeThreadType() { return {}; }
set_chrome_thread_type(::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType value)37139   void set_chrome_thread_type(::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType value) {
37140     static constexpr uint32_t field_id = FieldMetadata_ChromeThreadType::kFieldId;
37141     // Call the appropriate protozero::Message::Append(field_id, ...)
37142     // method based on the type of the field.
37143     ::protozero::internal::FieldWriter<
37144       ::protozero::proto_utils::ProtoSchemaType::kEnum>
37145         ::Append(*this, field_id, value);
37146   }
37147 
37148   using FieldMetadata_ReferenceTimestampUs =
37149     ::protozero::proto_utils::FieldMetadata<
37150       6,
37151       ::protozero::proto_utils::RepetitionType::kNotRepeated,
37152       ::protozero::proto_utils::ProtoSchemaType::kInt64,
37153       int64_t,
37154       ThreadDescriptor>;
37155 
37156   // Ceci n'est pas une pipe.
37157   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
37158   // type (and users are expected to use it as such, hence kCamelCase name).
37159   // It is declared as a function to keep protozero bindings header-only as
37160   // inline constexpr variables are not available until C++17 (while inline
37161   // functions are).
37162   // TODO(altimin): Use inline variable instead after adopting C++17.
kReferenceTimestampUs()37163   static constexpr FieldMetadata_ReferenceTimestampUs kReferenceTimestampUs() { return {}; }
set_reference_timestamp_us(int64_t value)37164   void set_reference_timestamp_us(int64_t value) {
37165     static constexpr uint32_t field_id = FieldMetadata_ReferenceTimestampUs::kFieldId;
37166     // Call the appropriate protozero::Message::Append(field_id, ...)
37167     // method based on the type of the field.
37168     ::protozero::internal::FieldWriter<
37169       ::protozero::proto_utils::ProtoSchemaType::kInt64>
37170         ::Append(*this, field_id, value);
37171   }
37172 
37173   using FieldMetadata_ReferenceThreadTimeUs =
37174     ::protozero::proto_utils::FieldMetadata<
37175       7,
37176       ::protozero::proto_utils::RepetitionType::kNotRepeated,
37177       ::protozero::proto_utils::ProtoSchemaType::kInt64,
37178       int64_t,
37179       ThreadDescriptor>;
37180 
37181   // Ceci n'est pas une pipe.
37182   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
37183   // type (and users are expected to use it as such, hence kCamelCase name).
37184   // It is declared as a function to keep protozero bindings header-only as
37185   // inline constexpr variables are not available until C++17 (while inline
37186   // functions are).
37187   // TODO(altimin): Use inline variable instead after adopting C++17.
kReferenceThreadTimeUs()37188   static constexpr FieldMetadata_ReferenceThreadTimeUs kReferenceThreadTimeUs() { return {}; }
set_reference_thread_time_us(int64_t value)37189   void set_reference_thread_time_us(int64_t value) {
37190     static constexpr uint32_t field_id = FieldMetadata_ReferenceThreadTimeUs::kFieldId;
37191     // Call the appropriate protozero::Message::Append(field_id, ...)
37192     // method based on the type of the field.
37193     ::protozero::internal::FieldWriter<
37194       ::protozero::proto_utils::ProtoSchemaType::kInt64>
37195         ::Append(*this, field_id, value);
37196   }
37197 
37198   using FieldMetadata_ReferenceThreadInstructionCount =
37199     ::protozero::proto_utils::FieldMetadata<
37200       8,
37201       ::protozero::proto_utils::RepetitionType::kNotRepeated,
37202       ::protozero::proto_utils::ProtoSchemaType::kInt64,
37203       int64_t,
37204       ThreadDescriptor>;
37205 
37206   // Ceci n'est pas une pipe.
37207   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
37208   // type (and users are expected to use it as such, hence kCamelCase name).
37209   // It is declared as a function to keep protozero bindings header-only as
37210   // inline constexpr variables are not available until C++17 (while inline
37211   // functions are).
37212   // TODO(altimin): Use inline variable instead after adopting C++17.
kReferenceThreadInstructionCount()37213   static constexpr FieldMetadata_ReferenceThreadInstructionCount kReferenceThreadInstructionCount() { return {}; }
set_reference_thread_instruction_count(int64_t value)37214   void set_reference_thread_instruction_count(int64_t value) {
37215     static constexpr uint32_t field_id = FieldMetadata_ReferenceThreadInstructionCount::kFieldId;
37216     // Call the appropriate protozero::Message::Append(field_id, ...)
37217     // method based on the type of the field.
37218     ::protozero::internal::FieldWriter<
37219       ::protozero::proto_utils::ProtoSchemaType::kInt64>
37220         ::Append(*this, field_id, value);
37221   }
37222 
37223   using FieldMetadata_LegacySortIndex =
37224     ::protozero::proto_utils::FieldMetadata<
37225       3,
37226       ::protozero::proto_utils::RepetitionType::kNotRepeated,
37227       ::protozero::proto_utils::ProtoSchemaType::kInt32,
37228       int32_t,
37229       ThreadDescriptor>;
37230 
37231   // Ceci n'est pas une pipe.
37232   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
37233   // type (and users are expected to use it as such, hence kCamelCase name).
37234   // It is declared as a function to keep protozero bindings header-only as
37235   // inline constexpr variables are not available until C++17 (while inline
37236   // functions are).
37237   // TODO(altimin): Use inline variable instead after adopting C++17.
kLegacySortIndex()37238   static constexpr FieldMetadata_LegacySortIndex kLegacySortIndex() { return {}; }
set_legacy_sort_index(int32_t value)37239   void set_legacy_sort_index(int32_t value) {
37240     static constexpr uint32_t field_id = FieldMetadata_LegacySortIndex::kFieldId;
37241     // Call the appropriate protozero::Message::Append(field_id, ...)
37242     // method based on the type of the field.
37243     ::protozero::internal::FieldWriter<
37244       ::protozero::proto_utils::ProtoSchemaType::kInt32>
37245         ::Append(*this, field_id, value);
37246   }
37247 };
37248 
37249 } // Namespace.
37250 } // Namespace.
37251 } // Namespace.
37252 #endif  // Include guard.
37253 /*
37254  * Copyright (C) 2020 The Android Open Source Project
37255  *
37256  * Licensed under the Apache License, Version 2.0 (the "License");
37257  * you may not use this file except in compliance with the License.
37258  * You may obtain a copy of the License at
37259  *
37260  *      http://www.apache.org/licenses/LICENSE-2.0
37261  *
37262  * Unless required by applicable law or agreed to in writing, software
37263  * distributed under the License is distributed on an "AS IS" BASIS,
37264  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
37265  * See the License for the specific language governing permissions and
37266  * limitations under the License.
37267  */
37268 
37269 // gen_amalgamated expanded: #include "perfetto/tracing/console_interceptor.h"
37270 
37271 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
37272 // gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
37273 // gen_amalgamated expanded: #include "perfetto/ext/base/optional.h"
37274 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
37275 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
37276 // gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_internal.h"
37277 
37278 // gen_amalgamated expanded: #include "protos/perfetto/common/interceptor_descriptor.gen.h"
37279 // gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
37280 // gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
37281 // gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.pbzero.h"
37282 // gen_amalgamated expanded: #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
37283 // gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
37284 // gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet_defaults.pbzero.h"
37285 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/process_descriptor.pbzero.h"
37286 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/thread_descriptor.pbzero.h"
37287 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_descriptor.pbzero.h"
37288 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.pbzero.h"
37289 
37290 #include <algorithm>
37291 #include <cmath>
37292 #include <tuple>
37293 
37294 namespace perfetto {
37295 
37296 // sRGB color.
37297 struct ConsoleColor {
37298   uint8_t r;
37299   uint8_t g;
37300   uint8_t b;
37301 };
37302 
37303 namespace {
37304 
37305 int g_output_fd_for_testing;
37306 
37307 // Google Turbo colormap.
37308 constexpr std::array<ConsoleColor, 16> kTurboColors = {{
37309     ConsoleColor{0x30, 0x12, 0x3b},
37310     ConsoleColor{0x40, 0x40, 0xa1},
37311     ConsoleColor{0x46, 0x6b, 0xe3},
37312     ConsoleColor{0x41, 0x93, 0xfe},
37313     ConsoleColor{0x28, 0xbb, 0xeb},
37314     ConsoleColor{0x17, 0xdc, 0xc2},
37315     ConsoleColor{0x32, 0xf1, 0x97},
37316     ConsoleColor{0x6d, 0xfd, 0x62},
37317     ConsoleColor{0xa4, 0xfc, 0x3b},
37318     ConsoleColor{0xcd, 0xeb, 0x34},
37319     ConsoleColor{0xed, 0xcf, 0x39},
37320     ConsoleColor{0xfd, 0xab, 0x33},
37321     ConsoleColor{0xfa, 0x7d, 0x20},
37322     ConsoleColor{0xea, 0x50, 0x0d},
37323     ConsoleColor{0xd0, 0x2f, 0x04},
37324     ConsoleColor{0xa9, 0x15, 0x01},
37325 }};
37326 
37327 constexpr size_t kHueBits = 4;
37328 constexpr uint32_t kMaxHue = kTurboColors.size() << kHueBits;
37329 constexpr uint8_t kLightness = 128u;
37330 constexpr ConsoleColor kWhiteColor{0xff, 0xff, 0xff};
37331 
37332 const char kDim[] = "\x1b[90m";
37333 const char kDefault[] = "\x1b[39m";
37334 const char kReset[] = "\x1b[0m";
37335 
37336 #define FMT_RGB_SET "\x1b[38;2;%d;%d;%dm"
37337 #define FMT_RGB_SET_BG "\x1b[48;2;%d;%d;%dm"
37338 
Mix(ConsoleColor a,ConsoleColor b,uint8_t ratio)37339 ConsoleColor Mix(ConsoleColor a, ConsoleColor b, uint8_t ratio) {
37340   return {
37341       static_cast<uint8_t>(a.r + (((b.r - a.r) * ratio) >> 8)),
37342       static_cast<uint8_t>(a.g + (((b.g - a.g) * ratio) >> 8)),
37343       static_cast<uint8_t>(a.b + (((b.b - a.b) * ratio) >> 8)),
37344   };
37345 }
37346 
HueToRGB(uint32_t hue)37347 ConsoleColor HueToRGB(uint32_t hue) {
37348   PERFETTO_DCHECK(hue < kMaxHue);
37349   uint32_t c1 = hue >> kHueBits;
37350   uint32_t c2 =
37351       std::min(static_cast<uint32_t>(kTurboColors.size() - 1), c1 + 1u);
37352   uint32_t ratio = hue & ((1 << kHueBits) - 1);
37353   return Mix(kTurboColors[c1], kTurboColors[c2],
37354              static_cast<uint8_t>(ratio | (ratio << kHueBits)));
37355 }
37356 
CounterToHue(uint32_t counter)37357 uint32_t CounterToHue(uint32_t counter) {
37358   // We split the hue space into 8 segments, reversing the order of bits so
37359   // successive counter values will be far from each other.
37360   uint32_t reversed =
37361       ((counter & 0x7) >> 2) | ((counter & 0x3)) | ((counter & 0x1) << 2);
37362   return reversed * kMaxHue / 8;
37363 }
37364 
37365 }  // namespace
37366 
37367 class ConsoleInterceptor::Delegate : public TrackEventStateTracker::Delegate {
37368  public:
37369   explicit Delegate(InterceptorContext&);
37370   ~Delegate() override;
37371 
37372   TrackEventStateTracker::SessionState* GetSessionState() override;
37373   void OnTrackUpdated(TrackEventStateTracker::Track&) override;
37374   void OnTrackEvent(const TrackEventStateTracker::Track&,
37375                     const TrackEventStateTracker::ParsedTrackEvent&) override;
37376 
37377  private:
37378   using SelfHandle = LockedHandle<ConsoleInterceptor>;
37379 
37380   InterceptorContext& context_;
37381   base::Optional<SelfHandle> locked_self_;
37382 };
37383 
37384 ConsoleInterceptor::~ConsoleInterceptor() = default;
37385 
ThreadLocalState(ThreadLocalStateArgs & args)37386 ConsoleInterceptor::ThreadLocalState::ThreadLocalState(
37387     ThreadLocalStateArgs& args) {
37388   if (auto self = args.GetInterceptorLocked()) {
37389     start_time_ns = self->start_time_ns_;
37390     use_colors = self->use_colors_;
37391     fd = self->fd_;
37392   }
37393 }
37394 
37395 ConsoleInterceptor::ThreadLocalState::~ThreadLocalState() = default;
37396 
Delegate(InterceptorContext & context)37397 ConsoleInterceptor::Delegate::Delegate(InterceptorContext& context)
37398     : context_(context) {}
37399 ConsoleInterceptor::Delegate::~Delegate() = default;
37400 
37401 TrackEventStateTracker::SessionState*
GetSessionState()37402 ConsoleInterceptor::Delegate::GetSessionState() {
37403   // When the session state is retrieved for the first time, it is cached (and
37404   // kept locked) until we return from OnTracePacket. This avoids having to lock
37405   // and unlock the instance multiple times per invocation.
37406   if (locked_self_.has_value())
37407     return &locked_self_.value()->session_state_;
37408   locked_self_ =
37409       base::make_optional<SelfHandle>(context_.GetInterceptorLocked());
37410   return &locked_self_.value()->session_state_;
37411 }
37412 
OnTrackUpdated(TrackEventStateTracker::Track & track)37413 void ConsoleInterceptor::Delegate::OnTrackUpdated(
37414     TrackEventStateTracker::Track& track) {
37415   auto track_color = HueToRGB(CounterToHue(track.index));
37416   std::array<char, 16> title;
37417   if (!track.name.empty()) {
37418     snprintf(title.data(), title.size(), "%s", track.name.c_str());
37419   } else if (track.pid && track.tid) {
37420     snprintf(title.data(), title.size(), "%u:%u",
37421              static_cast<uint32_t>(track.pid),
37422              static_cast<uint32_t>(track.tid));
37423   } else if (track.pid) {
37424     snprintf(title.data(), title.size(), "%" PRId64, track.pid);
37425   } else {
37426     snprintf(title.data(), title.size(), "%" PRIu64, track.uuid);
37427   }
37428   int title_width = static_cast<int>(title.size());
37429 
37430   auto& tls = context_.GetThreadLocalState();
37431   std::array<char, 128> message_prefix{};
37432   ssize_t written = 0;
37433   if (tls.use_colors) {
37434     written = snprintf(message_prefix.data(), message_prefix.size(),
37435                        FMT_RGB_SET_BG " %s%s %-*.*s", track_color.r,
37436                        track_color.g, track_color.b, kReset, kDim, title_width,
37437                        title_width, title.data());
37438   } else {
37439     written = snprintf(message_prefix.data(), message_prefix.size(), "%-*.*s",
37440                        title_width + 2, title_width, title.data());
37441   }
37442   if (written < 0)
37443     written = message_prefix.size();
37444   track.user_data.assign(message_prefix.begin(),
37445                          message_prefix.begin() + written);
37446 }
37447 
OnTrackEvent(const TrackEventStateTracker::Track & track,const TrackEventStateTracker::ParsedTrackEvent & event)37448 void ConsoleInterceptor::Delegate::OnTrackEvent(
37449     const TrackEventStateTracker::Track& track,
37450     const TrackEventStateTracker::ParsedTrackEvent& event) {
37451   // Start printing.
37452   auto& tls = context_.GetThreadLocalState();
37453   tls.buffer_pos = 0;
37454 
37455   // Print timestamp and track identifier.
37456   SetColor(context_, kDim);
37457   Printf(context_, "[%7.3lf] %.*s",
37458          static_cast<double>(event.timestamp_ns - tls.start_time_ns) / 1e9,
37459          static_cast<int>(track.user_data.size()), track.user_data.data());
37460 
37461   // Print category.
37462   Printf(context_, "%-5.*s ",
37463          std::min(5, static_cast<int>(event.category.size)),
37464          event.category.data);
37465 
37466   // Print stack depth.
37467   for (size_t i = 0; i < event.stack_depth; i++) {
37468     Printf(context_, "-  ");
37469   }
37470 
37471   // Print slice name.
37472   auto slice_color = HueToRGB(event.name_hash % kMaxHue);
37473   auto highlight_color = Mix(slice_color, kWhiteColor, kLightness);
37474   if (event.track_event.type() == protos::pbzero::TrackEvent::TYPE_SLICE_END) {
37475     SetColor(context_, kDefault);
37476     Printf(context_, "} ");
37477   }
37478   SetColor(context_, highlight_color);
37479   Printf(context_, "%.*s", static_cast<int>(event.name.size), event.name.data);
37480   SetColor(context_, kReset);
37481   if (event.track_event.type() ==
37482       protos::pbzero::TrackEvent::TYPE_SLICE_BEGIN) {
37483     SetColor(context_, kDefault);
37484     Printf(context_, " {");
37485   }
37486 
37487   // Print annotations.
37488   if (event.track_event.has_debug_annotations()) {
37489     PrintDebugAnnotations(context_, event.track_event, slice_color,
37490                           highlight_color);
37491   }
37492 
37493   // TODO(skyostil): Print typed arguments.
37494 
37495   // Print duration for longer events.
37496   constexpr uint64_t kNsPerMillisecond = 1000000u;
37497   if (event.duration_ns >= 10 * kNsPerMillisecond) {
37498     SetColor(context_, kDim);
37499     Printf(context_, " +%" PRIu64 "ms", event.duration_ns / kNsPerMillisecond);
37500   }
37501   SetColor(context_, kReset);
37502   Printf(context_, "\n");
37503 }
37504 
37505 // static
Register()37506 void ConsoleInterceptor::Register() {
37507   perfetto::protos::gen::InterceptorDescriptor desc;
37508   desc.set_name("console");
37509   Interceptor<ConsoleInterceptor>::Register(desc);
37510 }
37511 
37512 // static
SetOutputFdForTesting(int fd)37513 void ConsoleInterceptor::SetOutputFdForTesting(int fd) {
37514   g_output_fd_for_testing = fd;
37515 }
37516 
OnSetup(const SetupArgs & args)37517 void ConsoleInterceptor::OnSetup(const SetupArgs& args) {
37518   int fd = STDOUT_FILENO;
37519   if (g_output_fd_for_testing)
37520     fd = g_output_fd_for_testing;
37521 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
37522     !PERFETTO_BUILDFLAG(PERFETTO_OS_WASM)
37523   bool use_colors = isatty(fd);
37524 #else
37525   bool use_colors = false;
37526 #endif
37527   protos::pbzero::ConsoleConfig::Decoder config(
37528       args.config.interceptor_config().console_config_raw());
37529   if (config.has_enable_colors())
37530     use_colors = config.enable_colors();
37531   if (config.output() == protos::pbzero::ConsoleConfig::OUTPUT_STDOUT) {
37532     fd = STDOUT_FILENO;
37533   } else if (config.output() == protos::pbzero::ConsoleConfig::OUTPUT_STDERR) {
37534     fd = STDERR_FILENO;
37535   }
37536   fd_ = fd;
37537   use_colors_ = use_colors;
37538 }
37539 
OnStart(const StartArgs &)37540 void ConsoleInterceptor::OnStart(const StartArgs&) {
37541   start_time_ns_ = internal::TrackEventInternal::GetTimeNs();
37542 }
37543 
OnStop(const StopArgs &)37544 void ConsoleInterceptor::OnStop(const StopArgs&) {}
37545 
37546 // static
OnTracePacket(InterceptorContext context)37547 void ConsoleInterceptor::OnTracePacket(InterceptorContext context) {
37548   {
37549     auto& tls = context.GetThreadLocalState();
37550     Delegate delegate(context);
37551     perfetto::protos::pbzero::TracePacket::Decoder packet(
37552         context.packet_data.data, context.packet_data.size);
37553     TrackEventStateTracker::ProcessTracePacket(delegate, tls.sequence_state,
37554                                                packet);
37555   }  // (Potential) lock scope for session state.
37556   Flush(context);
37557 }
37558 
37559 // static
Printf(InterceptorContext & context,const char * format,...)37560 void ConsoleInterceptor::Printf(InterceptorContext& context,
37561                                 const char* format,
37562                                 ...) {
37563   auto& tls = context.GetThreadLocalState();
37564   ssize_t remaining = static_cast<ssize_t>(tls.message_buffer.size()) -
37565                       static_cast<ssize_t>(tls.buffer_pos);
37566   int written = 0;
37567   if (remaining > 0) {
37568     va_list args;
37569     va_start(args, format);
37570     written = vsnprintf(&tls.message_buffer[tls.buffer_pos],
37571                         static_cast<size_t>(remaining), format, args);
37572     PERFETTO_DCHECK(written >= 0);
37573     va_end(args);
37574   }
37575 
37576   // In case of buffer overflow, flush to the fd and write the latest message to
37577   // it directly instead.
37578   if (remaining <= 0 || written > remaining) {
37579     FILE* output = (tls.fd == STDOUT_FILENO) ? stdout : stderr;
37580     if (g_output_fd_for_testing) {
37581       output = fdopen(dup(g_output_fd_for_testing), "w");
37582     }
37583     Flush(context);
37584     va_list args;
37585     va_start(args, format);
37586     vfprintf(output, format, args);
37587     va_end(args);
37588     if (g_output_fd_for_testing) {
37589       fclose(output);
37590     }
37591   } else if (written > 0) {
37592     tls.buffer_pos += static_cast<size_t>(written);
37593   }
37594 }
37595 
37596 // static
Flush(InterceptorContext & context)37597 void ConsoleInterceptor::Flush(InterceptorContext& context) {
37598   auto& tls = context.GetThreadLocalState();
37599   ssize_t res = base::WriteAll(tls.fd, &tls.message_buffer[0], tls.buffer_pos);
37600   PERFETTO_DCHECK(res == static_cast<ssize_t>(tls.buffer_pos));
37601   tls.buffer_pos = 0;
37602 }
37603 
37604 // static
SetColor(InterceptorContext & context,const ConsoleColor & color)37605 void ConsoleInterceptor::SetColor(InterceptorContext& context,
37606                                   const ConsoleColor& color) {
37607   auto& tls = context.GetThreadLocalState();
37608   if (!tls.use_colors)
37609     return;
37610   Printf(context, FMT_RGB_SET, color.r, color.g, color.b);
37611 }
37612 
37613 // static
SetColor(InterceptorContext & context,const char * color)37614 void ConsoleInterceptor::SetColor(InterceptorContext& context,
37615                                   const char* color) {
37616   auto& tls = context.GetThreadLocalState();
37617   if (!tls.use_colors)
37618     return;
37619   Printf(context, "%s", color);
37620 }
37621 
37622 // static
PrintDebugAnnotations(InterceptorContext & context,const protos::pbzero::TrackEvent_Decoder & track_event,const ConsoleColor & slice_color,const ConsoleColor & highlight_color)37623 void ConsoleInterceptor::PrintDebugAnnotations(
37624     InterceptorContext& context,
37625     const protos::pbzero::TrackEvent_Decoder& track_event,
37626     const ConsoleColor& slice_color,
37627     const ConsoleColor& highlight_color) {
37628   SetColor(context, slice_color);
37629   Printf(context, "(");
37630 
37631   bool is_first = true;
37632   for (auto it = track_event.debug_annotations(); it; it++) {
37633     perfetto::protos::pbzero::DebugAnnotation::Decoder annotation(*it);
37634     SetColor(context, slice_color);
37635     if (!is_first)
37636       Printf(context, ", ");
37637 
37638     PrintDebugAnnotationName(context, annotation);
37639     Printf(context, ":");
37640 
37641     SetColor(context, highlight_color);
37642     PrintDebugAnnotationValue(context, annotation);
37643 
37644     is_first = false;
37645   }
37646   SetColor(context, slice_color);
37647   Printf(context, ")");
37648 }
37649 
37650 // static
PrintDebugAnnotationName(InterceptorContext & context,const perfetto::protos::pbzero::DebugAnnotation::Decoder & annotation)37651 void ConsoleInterceptor::PrintDebugAnnotationName(
37652     InterceptorContext& context,
37653     const perfetto::protos::pbzero::DebugAnnotation::Decoder& annotation) {
37654   auto& tls = context.GetThreadLocalState();
37655   protozero::ConstChars name{};
37656   if (annotation.name_iid()) {
37657     name.data =
37658         tls.sequence_state.debug_annotation_names[annotation.name_iid()].data();
37659     name.size =
37660         tls.sequence_state.debug_annotation_names[annotation.name_iid()].size();
37661   } else if (annotation.has_name()) {
37662     name.data = annotation.name().data;
37663     name.size = annotation.name().size;
37664   }
37665   Printf(context, "%.*s", static_cast<int>(name.size), name.data);
37666 }
37667 
37668 // static
PrintDebugAnnotationValue(InterceptorContext & context,const perfetto::protos::pbzero::DebugAnnotation::Decoder & annotation)37669 void ConsoleInterceptor::PrintDebugAnnotationValue(
37670     InterceptorContext& context,
37671     const perfetto::protos::pbzero::DebugAnnotation::Decoder& annotation) {
37672   if (annotation.has_bool_value()) {
37673     Printf(context, "%s", annotation.bool_value() ? "true" : "false");
37674   } else if (annotation.has_uint_value()) {
37675     Printf(context, "%" PRIu64, annotation.uint_value());
37676   } else if (annotation.has_int_value()) {
37677     Printf(context, "%" PRId64, annotation.int_value());
37678   } else if (annotation.has_double_value()) {
37679     Printf(context, "%f", annotation.double_value());
37680   } else if (annotation.has_string_value()) {
37681     Printf(context, "%.*s", static_cast<int>(annotation.string_value().size),
37682            annotation.string_value().data);
37683   } else if (annotation.has_pointer_value()) {
37684     Printf(context, "%p", reinterpret_cast<void*>(annotation.pointer_value()));
37685   } else if (annotation.has_legacy_json_value()) {
37686     Printf(context, "%.*s",
37687            static_cast<int>(annotation.legacy_json_value().size),
37688            annotation.legacy_json_value().data);
37689   } else if (annotation.has_dict_entries()) {
37690     Printf(context, "{");
37691     bool is_first = true;
37692     for (auto it = annotation.dict_entries(); it; ++it) {
37693       if (!is_first)
37694         Printf(context, ", ");
37695       perfetto::protos::pbzero::DebugAnnotation::Decoder key_value(*it);
37696       PrintDebugAnnotationName(context, key_value);
37697       Printf(context, ":");
37698       PrintDebugAnnotationValue(context, key_value);
37699       is_first = false;
37700     }
37701     Printf(context, "}");
37702   } else if (annotation.has_array_values()) {
37703     Printf(context, "[");
37704     bool is_first = true;
37705     for (auto it = annotation.array_values(); it; ++it) {
37706       if (!is_first)
37707         Printf(context, ", ");
37708       perfetto::protos::pbzero::DebugAnnotation::Decoder key_value(*it);
37709       PrintDebugAnnotationValue(context, key_value);
37710       is_first = false;
37711     }
37712     Printf(context, "]");
37713   } else {
37714     Printf(context, "{}");
37715   }
37716 }
37717 
37718 }  // namespace perfetto
37719 // gen_amalgamated begin source: src/tracing/data_source.cc
37720 /*
37721  * Copyright (C) 2019 The Android Open Source Project
37722  *
37723  * Licensed under the Apache License, Version 2.0 (the "License");
37724  * you may not use this file except in compliance with the License.
37725  * You may obtain a copy of the License at
37726  *
37727  *      http://www.apache.org/licenses/LICENSE-2.0
37728  *
37729  * Unless required by applicable law or agreed to in writing, software
37730  * distributed under the License is distributed on an "AS IS" BASIS,
37731  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
37732  * See the License for the specific language governing permissions and
37733  * limitations under the License.
37734  */
37735 
37736 // gen_amalgamated expanded: #include "perfetto/tracing/data_source.h"
37737 
37738 namespace perfetto {
37739 
37740 DataSourceBase::StopArgs::~StopArgs() = default;
37741 DataSourceBase::~DataSourceBase() = default;
OnSetup(const SetupArgs &)37742 void DataSourceBase::OnSetup(const SetupArgs&) {}
OnStart(const StartArgs &)37743 void DataSourceBase::OnStart(const StartArgs&) {}
OnStop(const StopArgs &)37744 void DataSourceBase::OnStop(const StopArgs&) {}
37745 
37746 }  // namespace perfetto
37747 // gen_amalgamated begin source: src/tracing/debug_annotation.cc
37748 /*
37749  * Copyright (C) 2019 The Android Open Source Project
37750  *
37751  * Licensed under the Apache License, Version 2.0 (the "License");
37752  * you may not use this file except in compliance with the License.
37753  * You may obtain a copy of the License at
37754  *
37755  *      http://www.apache.org/licenses/LICENSE-2.0
37756  *
37757  * Unless required by applicable law or agreed to in writing, software
37758  * distributed under the License is distributed on an "AS IS" BASIS,
37759  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
37760  * See the License for the specific language governing permissions and
37761  * limitations under the License.
37762  */
37763 
37764 // gen_amalgamated expanded: #include "perfetto/tracing/debug_annotation.h"
37765 
37766 // gen_amalgamated expanded: #include "perfetto/tracing/traced_value.h"
37767 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
37768 
37769 namespace perfetto {
37770 
37771 DebugAnnotation::~DebugAnnotation() = default;
37772 
WriteIntoTracedValue(TracedValue context) const37773 void DebugAnnotation::WriteIntoTracedValue(TracedValue context) const {
37774   Add(context.context_);
37775 }
37776 
37777 }  // namespace perfetto
37778 // gen_amalgamated begin source: src/tracing/event_context.cc
37779 /*
37780  * Copyright (C) 2019 The Android Open Source Project
37781  *
37782  * Licensed under the Apache License, Version 2.0 (the "License");
37783  * you may not use this file except in compliance with the License.
37784  * You may obtain a copy of the License at
37785  *
37786  *      http://www.apache.org/licenses/LICENSE-2.0
37787  *
37788  * Unless required by applicable law or agreed to in writing, software
37789  * distributed under the License is distributed on an "AS IS" BASIS,
37790  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
37791  * See the License for the specific language governing permissions and
37792  * limitations under the License.
37793  */
37794 
37795 // gen_amalgamated expanded: #include "perfetto/tracing/event_context.h"
37796 
37797 // gen_amalgamated expanded: #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
37798 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.pbzero.h"
37799 
37800 namespace perfetto {
37801 
EventContext(EventContext::TracePacketHandle trace_packet,internal::TrackEventIncrementalState * incremental_state)37802 EventContext::EventContext(
37803     EventContext::TracePacketHandle trace_packet,
37804     internal::TrackEventIncrementalState* incremental_state)
37805     : trace_packet_(std::move(trace_packet)),
37806       event_(trace_packet_->set_track_event()),
37807       incremental_state_(incremental_state) {}
37808 
~EventContext()37809 EventContext::~EventContext() {
37810   if (!trace_packet_)
37811     return;
37812 
37813   // When the track event is finalized (i.e., the context is destroyed), we
37814   // should flush any newly seen interned data to the trace. The data has
37815   // earlier been written to a heap allocated protobuf message
37816   // (|serialized_interned_data|). Here we just need to flush it to the main
37817   // trace.
37818   auto& serialized_interned_data = incremental_state_->serialized_interned_data;
37819   if (PERFETTO_LIKELY(serialized_interned_data.empty()))
37820     return;
37821 
37822   auto ranges = serialized_interned_data.GetRanges();
37823   trace_packet_->AppendScatteredBytes(
37824       perfetto::protos::pbzero::TracePacket::kInternedDataFieldNumber,
37825       &ranges[0], ranges.size());
37826 
37827   // Reset the message but keep one buffer allocated for future use.
37828   serialized_interned_data.Reset();
37829 }
37830 
37831 }  // namespace perfetto
37832 // gen_amalgamated begin source: src/tracing/interceptor.cc
37833 /*
37834  * Copyright (C) 2020 The Android Open Source Project
37835  *
37836  * Licensed under the Apache License, Version 2.0 (the "License");
37837  * you may not use this file except in compliance with the License.
37838  * You may obtain a copy of the License at
37839  *
37840  *      http://www.apache.org/licenses/LICENSE-2.0
37841  *
37842  * Unless required by applicable law or agreed to in writing, software
37843  * distributed under the License is distributed on an "AS IS" BASIS,
37844  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
37845  * See the License for the specific language governing permissions and
37846  * limitations under the License.
37847  */
37848 
37849 // gen_amalgamated expanded: #include "perfetto/tracing/interceptor.h"
37850 
37851 // gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_muxer.h"
37852 
37853 namespace perfetto {
37854 
37855 InterceptorBase::~InterceptorBase() = default;
37856 InterceptorBase::ThreadLocalState::~ThreadLocalState() = default;
37857 
37858 // static
RegisterImpl(const InterceptorDescriptor & descriptor,std::function<std::unique_ptr<InterceptorBase> ()> factory,InterceptorBase::TLSFactory tls_factory,InterceptorBase::TracePacketCallback on_trace_packet)37859 void InterceptorBase::RegisterImpl(
37860     const InterceptorDescriptor& descriptor,
37861     std::function<std::unique_ptr<InterceptorBase>()> factory,
37862     InterceptorBase::TLSFactory tls_factory,
37863     InterceptorBase::TracePacketCallback on_trace_packet) {
37864   auto* tracing_impl = internal::TracingMuxer::Get();
37865   tracing_impl->RegisterInterceptor(descriptor, factory, tls_factory,
37866                                     on_trace_packet);
37867 }
37868 
37869 }  // namespace perfetto
37870 // gen_amalgamated begin source: src/tracing/internal/checked_scope.cc
37871 /*
37872  * Copyright (C) 2021 The Android Open Source Project
37873  *
37874  * Licensed under the Apache License, Version 2.0 (the "License");
37875  * you may not use this file except in compliance with the License.
37876  * You may obtain a copy of the License at
37877  *
37878  *      http://www.apache.org/licenses/LICENSE-2.0
37879  *
37880  * Unless required by applicable law or agreed to in writing, software
37881  * distributed under the License is distributed on an "AS IS" BASIS,
37882  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
37883  * See the License for the specific language governing permissions and
37884  * limitations under the License.
37885  */
37886 
37887 // gen_amalgamated expanded: #include "perfetto/tracing/internal/checked_scope.h"
37888 
37889 #include <utility>
37890 
37891 namespace perfetto {
37892 namespace internal {
37893 
37894 #if PERFETTO_DCHECK_IS_ON()
CheckedScope(CheckedScope * parent_scope)37895 CheckedScope::CheckedScope(CheckedScope* parent_scope)
37896     : parent_scope_(parent_scope) {
37897   if (parent_scope_) {
37898     PERFETTO_DCHECK(parent_scope_->is_active());
37899     parent_scope_->set_is_active(false);
37900   }
37901 }
37902 
~CheckedScope()37903 CheckedScope::~CheckedScope() {
37904   Reset();
37905 }
37906 
Reset()37907 void CheckedScope::Reset() {
37908   if (!is_active_) {
37909     // The only case when inactive scope could be destroyed is when Reset() was
37910     // called explicitly or the contents of the object were moved away.
37911     PERFETTO_DCHECK(deleted_);
37912     return;
37913   }
37914   is_active_ = false;
37915   deleted_ = true;
37916   if (parent_scope_)
37917     parent_scope_->set_is_active(true);
37918 }
37919 
CheckedScope(CheckedScope && other)37920 CheckedScope::CheckedScope(CheckedScope&& other) {
37921   *this = std::move(other);
37922 }
37923 
operator =(CheckedScope && other)37924 CheckedScope& CheckedScope::operator=(CheckedScope&& other) {
37925   is_active_ = other.is_active_;
37926   parent_scope_ = other.parent_scope_;
37927   deleted_ = other.deleted_;
37928 
37929   other.is_active_ = false;
37930   other.parent_scope_ = nullptr;
37931   other.deleted_ = true;
37932 
37933   return *this;
37934 }
37935 #endif
37936 
37937 }  // namespace internal
37938 }  // namespace perfetto
37939 // gen_amalgamated begin source: src/tracing/internal/interceptor_trace_writer.cc
37940 // gen_amalgamated begin header: include/perfetto/tracing/internal/interceptor_trace_writer.h
37941 /*
37942  * Copyright (C) 2020 The Android Open Source Project
37943  *
37944  * Licensed under the Apache License, Version 2.0 (the "License");
37945  * you may not use this file except in compliance with the License.
37946  * You may obtain a copy of the License at
37947  *
37948  *      http://www.apache.org/licenses/LICENSE-2.0
37949  *
37950  * Unless required by applicable law or agreed to in writing, software
37951  * distributed under the License is distributed on an "AS IS" BASIS,
37952  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
37953  * See the License for the specific language governing permissions and
37954  * limitations under the License.
37955  */
37956 
37957 #ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_INTERCEPTOR_TRACE_WRITER_H_
37958 #define INCLUDE_PERFETTO_TRACING_INTERNAL_INTERCEPTOR_TRACE_WRITER_H_
37959 
37960 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
37961 // gen_amalgamated expanded: #include "perfetto/tracing/interceptor.h"
37962 // gen_amalgamated expanded: #include "perfetto/tracing/internal/basic_types.h"
37963 // gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
37964 // gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
37965 
37966 namespace perfetto {
37967 namespace internal {
37968 
37969 // A heap-backed trace writer used to reroute trace packets to an interceptor.
37970 class InterceptorTraceWriter : public TraceWriterBase {
37971  public:
37972   InterceptorTraceWriter(std::unique_ptr<InterceptorBase::ThreadLocalState> tls,
37973                          InterceptorBase::TracePacketCallback packet_callback,
37974                          DataSourceStaticState* static_state,
37975                          uint32_t instance_index);
37976   ~InterceptorTraceWriter() override;
37977 
37978   // TraceWriterBase implementation.
37979   protozero::MessageHandle<protos::pbzero::TracePacket> NewTracePacket()
37980       override;
37981   void Flush(std::function<void()> callback = {}) override;
37982   uint64_t written() const override;
37983 
37984  private:
37985   std::unique_ptr<InterceptorBase::ThreadLocalState> tls_;
37986   InterceptorBase::TracePacketCallback packet_callback_;
37987 
37988   protozero::HeapBuffered<protos::pbzero::TracePacket> cur_packet_;
37989   uint64_t bytes_written_ = 0;
37990 
37991   // Static state of the data source we are intercepting.
37992   DataSourceStaticState* const static_state_;
37993 
37994   // Index of the data source tracing session which we are intercepting
37995   // (0...kMaxDataSourceInstances - 1). Used to look up this interceptor's
37996   // session state (i.e., the Interceptor class instance) in the
37997   // DataSourceStaticState::instances array.
37998   const uint32_t instance_index_;
37999 
38000   const uint32_t sequence_id_;
38001 
38002   static std::atomic<uint32_t> next_sequence_id_;
38003 };
38004 
38005 }  // namespace internal
38006 }  // namespace perfetto
38007 
38008 #endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_INTERCEPTOR_TRACE_WRITER_H_
38009 /*
38010  * Copyright (C) 2020 The Android Open Source Project
38011  *
38012  * Licensed under the Apache License, Version 2.0 (the "License");
38013  * you may not use this file except in compliance with the License.
38014  * You may obtain a copy of the License at
38015  *
38016  *      http://www.apache.org/licenses/LICENSE-2.0
38017  *
38018  * Unless required by applicable law or agreed to in writing, software
38019  * distributed under the License is distributed on an "AS IS" BASIS,
38020  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
38021  * See the License for the specific language governing permissions and
38022  * limitations under the License.
38023  */
38024 
38025 // gen_amalgamated expanded: #include "perfetto/tracing/internal/interceptor_trace_writer.h"
38026 
38027 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
38028 
38029 namespace perfetto {
38030 namespace internal {
38031 
38032 // static
38033 std::atomic<uint32_t> InterceptorTraceWriter::next_sequence_id_{};
38034 
InterceptorTraceWriter(std::unique_ptr<InterceptorBase::ThreadLocalState> tls,InterceptorBase::TracePacketCallback packet_callback,DataSourceStaticState * static_state,uint32_t instance_index)38035 InterceptorTraceWriter::InterceptorTraceWriter(
38036     std::unique_ptr<InterceptorBase::ThreadLocalState> tls,
38037     InterceptorBase::TracePacketCallback packet_callback,
38038     DataSourceStaticState* static_state,
38039     uint32_t instance_index)
38040     : tls_(std::move(tls)),
38041       packet_callback_(std::move(packet_callback)),
38042       static_state_(static_state),
38043       instance_index_(instance_index),
38044       sequence_id_(++next_sequence_id_) {}
38045 
38046 InterceptorTraceWriter::~InterceptorTraceWriter() = default;
38047 
38048 protozero::MessageHandle<protos::pbzero::TracePacket>
NewTracePacket()38049 InterceptorTraceWriter::NewTracePacket() {
38050   Flush();
38051   auto packet = TraceWriter::TracePacketHandle(cur_packet_.get());
38052   packet->set_trusted_packet_sequence_id(sequence_id_);
38053   return packet;
38054 }
38055 
Flush(std::function<void ()> callback)38056 void InterceptorTraceWriter::Flush(std::function<void()> callback) {
38057   if (!cur_packet_.empty()) {
38058     InterceptorBase::TracePacketCallbackArgs args{};
38059     args.static_state = static_state_;
38060     args.instance_index = instance_index_;
38061     args.tls = tls_.get();
38062 
38063     const auto& slices = cur_packet_.GetSlices();
38064     if (slices.size() == 1) {
38065       // Fast path: the current packet fits into a single slice.
38066       auto slice_range = slices.begin()->GetUsedRange();
38067       args.packet_data = protozero::ConstBytes{
38068           slice_range.begin,
38069           static_cast<size_t>(slice_range.end - slice_range.begin)};
38070       bytes_written_ += static_cast<uint64_t>(args.packet_data.size);
38071       packet_callback_(std::move(args));
38072     } else {
38073       // Fallback: stitch together multiple slices.
38074       auto stitched_data = cur_packet_.SerializeAsArray();
38075       args.packet_data =
38076           protozero::ConstBytes{stitched_data.data(), stitched_data.size()};
38077       bytes_written_ += static_cast<uint64_t>(stitched_data.size());
38078       packet_callback_(std::move(args));
38079     }
38080     cur_packet_.Reset();
38081   }
38082   if (callback)
38083     callback();
38084 }
38085 
written() const38086 uint64_t InterceptorTraceWriter::written() const {
38087   return bytes_written_;
38088 }
38089 
38090 }  // namespace internal
38091 }  // namespace perfetto
38092 // gen_amalgamated begin source: src/tracing/internal/tracing_backend_fake.cc
38093 // gen_amalgamated begin header: include/perfetto/tracing/internal/tracing_backend_fake.h
38094 /*
38095  * Copyright (C) 2021 The Android Open Source Project
38096  *
38097  * Licensed under the Apache License, Version 2.0 (the "License");
38098  * you may not use this file except in compliance with the License.
38099  * You may obtain a copy of the License at
38100  *
38101  *      http://www.apache.org/licenses/LICENSE-2.0
38102  *
38103  * Unless required by applicable law or agreed to in writing, software
38104  * distributed under the License is distributed on an "AS IS" BASIS,
38105  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
38106  * See the License for the specific language governing permissions and
38107  * limitations under the License.
38108  */
38109 
38110 #ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_TRACING_BACKEND_FAKE_H_
38111 #define INCLUDE_PERFETTO_TRACING_INTERNAL_TRACING_BACKEND_FAKE_H_
38112 
38113 // gen_amalgamated expanded: #include "perfetto/base/export.h"
38114 // gen_amalgamated expanded: #include "perfetto/tracing/tracing_backend.h"
38115 
38116 namespace perfetto {
38117 namespace internal {
38118 
38119 // A built-in implementation of TracingBackend that fails any attempt to create
38120 // a tracing session.
38121 class PERFETTO_EXPORT TracingBackendFake : public TracingBackend {
38122  public:
38123   static TracingBackend* GetInstance();
38124 
38125   // TracingBackend implementation.
38126   std::unique_ptr<ProducerEndpoint> ConnectProducer(
38127       const ConnectProducerArgs&) override;
38128   std::unique_ptr<ConsumerEndpoint> ConnectConsumer(
38129       const ConnectConsumerArgs&) override;
38130 
38131  private:
38132   TracingBackendFake();
38133 };
38134 
38135 }  // namespace internal
38136 }  // namespace perfetto
38137 
38138 #endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_TRACING_BACKEND_FAKE_H_
38139 /*
38140  * Copyright (C) 2021 The Android Open Source Project
38141  *
38142  * Licensed under the Apache License, Version 2.0 (the "License");
38143  * you may not use this file except in compliance with the License.
38144  * You may obtain a copy of the License at
38145  *
38146  *      http://www.apache.org/licenses/LICENSE-2.0
38147  *
38148  * Unless required by applicable law or agreed to in writing, software
38149  * distributed under the License is distributed on an "AS IS" BASIS,
38150  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
38151  * See the License for the specific language governing permissions and
38152  * limitations under the License.
38153  */
38154 
38155 // gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_backend_fake.h"
38156 
38157 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
38158 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
38159 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
38160 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
38161 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
38162 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
38163 
38164 namespace perfetto {
38165 namespace internal {
38166 
38167 namespace {
38168 
38169 class UnsupportedProducerEndpoint : public ProducerEndpoint {
38170  public:
UnsupportedProducerEndpoint(Producer * producer,base::TaskRunner * task_runner)38171   UnsupportedProducerEndpoint(Producer* producer, base::TaskRunner* task_runner)
38172       : producer_(producer), task_runner_(task_runner) {
38173     // The SDK will attempt to reconnect the producer, so instead we allow it
38174     // to connect successfully, but never start any sessions.
38175     auto weak_ptr = weak_ptr_factory_.GetWeakPtr();
38176     task_runner_->PostTask([weak_ptr] {
38177       if (weak_ptr)
38178         weak_ptr->producer_->OnConnect();
38179     });
38180   }
~UnsupportedProducerEndpoint()38181   ~UnsupportedProducerEndpoint() override { producer_->OnDisconnect(); }
38182 
RegisterDataSource(const DataSourceDescriptor &)38183   void RegisterDataSource(const DataSourceDescriptor&) override {}
UnregisterDataSource(const std::string &)38184   void UnregisterDataSource(const std::string& /*name*/) override {}
38185 
RegisterTraceWriter(uint32_t,uint32_t)38186   void RegisterTraceWriter(uint32_t /*writer_id*/,
38187                            uint32_t /*target_buffer*/) override {}
UnregisterTraceWriter(uint32_t)38188   void UnregisterTraceWriter(uint32_t /*writer_id*/) override {}
38189 
CommitData(const CommitDataRequest &,CommitDataCallback callback={})38190   void CommitData(const CommitDataRequest&,
38191                   CommitDataCallback callback = {}) override {
38192     callback();
38193   }
38194 
shared_memory() const38195   SharedMemory* shared_memory() const override { return nullptr; }
shared_buffer_page_size_kb() const38196   size_t shared_buffer_page_size_kb() const override { return 0; }
38197 
CreateTraceWriter(BufferID,BufferExhaustedPolicy=BufferExhaustedPolicy::kDefault)38198   std::unique_ptr<TraceWriter> CreateTraceWriter(
38199       BufferID /*target_buffer*/,
38200       BufferExhaustedPolicy = BufferExhaustedPolicy::kDefault) override {
38201     return nullptr;
38202   }
38203 
MaybeSharedMemoryArbiter()38204   SharedMemoryArbiter* MaybeSharedMemoryArbiter() override { return nullptr; }
IsShmemProvidedByProducer() const38205   bool IsShmemProvidedByProducer() const override { return false; }
38206 
NotifyFlushComplete(FlushRequestID)38207   void NotifyFlushComplete(FlushRequestID) override {}
NotifyDataSourceStarted(DataSourceInstanceID)38208   void NotifyDataSourceStarted(DataSourceInstanceID) override {}
NotifyDataSourceStopped(DataSourceInstanceID)38209   void NotifyDataSourceStopped(DataSourceInstanceID) override {}
ActivateTriggers(const std::vector<std::string> &)38210   void ActivateTriggers(const std::vector<std::string>&) override {}
38211 
Sync(std::function<void ()> callback)38212   void Sync(std::function<void()> callback) override { callback(); }
38213 
38214  private:
38215   Producer* const producer_;
38216   base::TaskRunner* const task_runner_;
38217   base::WeakPtrFactory<UnsupportedProducerEndpoint> weak_ptr_factory_{
38218       this};  // Keep last.
38219 };
38220 
38221 class UnsupportedConsumerEndpoint : public ConsumerEndpoint {
38222  public:
UnsupportedConsumerEndpoint(Consumer * consumer,base::TaskRunner * task_runner)38223   UnsupportedConsumerEndpoint(Consumer* consumer, base::TaskRunner* task_runner)
38224       : consumer_(consumer), task_runner_(task_runner) {
38225     // The SDK will not to reconnect the consumer, so we just disconnect it
38226     // immediately, which will cancel the tracing session.
38227     auto weak_this = weak_ptr_factory_.GetWeakPtr();
38228     task_runner_->PostTask([weak_this] {
38229       if (weak_this)
38230         weak_this->consumer_->OnDisconnect();
38231     });
38232   }
38233   ~UnsupportedConsumerEndpoint() override = default;
38234 
EnableTracing(const TraceConfig &,base::ScopedFile=base::ScopedFile ())38235   void EnableTracing(const TraceConfig&,
38236                      base::ScopedFile = base::ScopedFile()) override {}
ChangeTraceConfig(const TraceConfig &)38237   void ChangeTraceConfig(const TraceConfig&) override {}
38238 
StartTracing()38239   void StartTracing() override {}
DisableTracing()38240   void DisableTracing() override {}
38241 
Flush(uint32_t,FlushCallback callback)38242   void Flush(uint32_t /*timeout_ms*/, FlushCallback callback) override {
38243     callback(/*success=*/false);
38244   }
38245 
ReadBuffers()38246   void ReadBuffers() override {}
FreeBuffers()38247   void FreeBuffers() override {}
38248 
Detach(const std::string &)38249   void Detach(const std::string& /*key*/) override {}
Attach(const std::string &)38250   void Attach(const std::string& /*key*/) override {}
38251 
GetTraceStats()38252   void GetTraceStats() override {}
ObserveEvents(uint32_t)38253   void ObserveEvents(uint32_t /*events_mask*/) override {}
QueryServiceState(QueryServiceStateCallback)38254   void QueryServiceState(QueryServiceStateCallback) override {}
QueryCapabilities(QueryCapabilitiesCallback)38255   void QueryCapabilities(QueryCapabilitiesCallback) override {}
38256 
SaveTraceForBugreport(SaveTraceForBugreportCallback)38257   void SaveTraceForBugreport(SaveTraceForBugreportCallback) override {}
38258 
38259  private:
38260   Consumer* const consumer_;
38261   base::TaskRunner* const task_runner_;
38262   base::WeakPtrFactory<UnsupportedConsumerEndpoint> weak_ptr_factory_{
38263       this};  // Keep last.
38264 };
38265 
38266 }  // namespace
38267 
38268 // static
GetInstance()38269 TracingBackend* TracingBackendFake::GetInstance() {
38270   static auto* instance = new TracingBackendFake();
38271   return instance;
38272 }
38273 
38274 TracingBackendFake::TracingBackendFake() = default;
38275 
ConnectProducer(const ConnectProducerArgs & args)38276 std::unique_ptr<ProducerEndpoint> TracingBackendFake::ConnectProducer(
38277     const ConnectProducerArgs& args) {
38278   return std::unique_ptr<ProducerEndpoint>(
38279       new UnsupportedProducerEndpoint(args.producer, args.task_runner));
38280 }
38281 
ConnectConsumer(const ConnectConsumerArgs & args)38282 std::unique_ptr<ConsumerEndpoint> TracingBackendFake::ConnectConsumer(
38283     const ConnectConsumerArgs& args) {
38284   return std::unique_ptr<ConsumerEndpoint>(
38285       new UnsupportedConsumerEndpoint(args.consumer, args.task_runner));
38286 }
38287 
38288 }  // namespace internal
38289 }  // namespace perfetto
38290 // gen_amalgamated begin source: src/tracing/internal/tracing_muxer_fake.cc
38291 // gen_amalgamated begin header: src/tracing/internal/tracing_muxer_fake.h
38292 /*
38293  * Copyright (C) 2021 The Android Open Source Project
38294  *
38295  * Licensed under the Apache License, Version 2.0 (the "License");
38296  * you may not use this file except in compliance with the License.
38297  * You may obtain a copy of the License at
38298  *
38299  *      http://www.apache.org/licenses/LICENSE-2.0
38300  *
38301  * Unless required by applicable law or agreed to in writing, software
38302  * distributed under the License is distributed on an "AS IS" BASIS,
38303  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
38304  * See the License for the specific language governing permissions and
38305  * limitations under the License.
38306  */
38307 
38308 #ifndef SRC_TRACING_INTERNAL_TRACING_MUXER_FAKE_H_
38309 #define SRC_TRACING_INTERNAL_TRACING_MUXER_FAKE_H_
38310 
38311 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
38312 // gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_muxer.h"
38313 
38314 namespace perfetto {
38315 namespace internal {
38316 
38317 // An always-fail implementation of TracingMuxer. Before tracing has been
38318 // initialiazed, all muxer operations will route here and fail with a helpful
38319 // error message. This is to avoid introducing null checks in
38320 // performance-critical parts of the codebase.
38321 class TracingMuxerFake : public TracingMuxer {
38322   class FakePlatform : public Platform {
38323    public:
38324     ~FakePlatform() override;
38325     ThreadLocalObject* GetOrCreateThreadLocalObject() override;
38326     std::unique_ptr<base::TaskRunner> CreateTaskRunner(
38327         const CreateTaskRunnerArgs&) override;
38328     std::string GetCurrentProcessName() override;
38329 
38330     static FakePlatform instance;
38331   };
38332 
38333  public:
TracingMuxerFake()38334   TracingMuxerFake() : TracingMuxer(&FakePlatform::instance) {}
38335 
Get()38336   static constexpr TracingMuxerFake* Get() {
38337 #if PERFETTO_HAS_NO_DESTROY()
38338     return &instance;
38339 #else
38340     return nullptr;
38341 #endif
38342   }
38343 
38344   // TracingMuxer implementation.
38345   bool RegisterDataSource(const DataSourceDescriptor&,
38346                           DataSourceFactory,
38347                           DataSourceStaticState*) override;
38348   std::unique_ptr<TraceWriterBase> CreateTraceWriter(
38349       DataSourceStaticState*,
38350       uint32_t data_source_instance_index,
38351       DataSourceState*,
38352       BufferExhaustedPolicy buffer_exhausted_policy) override;
38353   void DestroyStoppedTraceWritersForCurrentThread() override;
38354   void RegisterInterceptor(const InterceptorDescriptor&,
38355                            InterceptorFactory,
38356                            InterceptorBase::TLSFactory,
38357                            InterceptorBase::TracePacketCallback) override;
38358 
38359  private:
38360   static TracingMuxerFake instance;
38361 };
38362 
38363 }  // namespace internal
38364 }  // namespace perfetto
38365 
38366 #endif  // SRC_TRACING_INTERNAL_TRACING_MUXER_FAKE_H_
38367 /*
38368  * Copyright (C) 2021 The Android Open Source Project
38369  *
38370  * Licensed under the Apache License, Version 2.0 (the "License");
38371  * you may not use this file except in compliance with the License.
38372  * You may obtain a copy of the License at
38373  *
38374  *      http://www.apache.org/licenses/LICENSE-2.0
38375  *
38376  * Unless required by applicable law or agreed to in writing, software
38377  * distributed under the License is distributed on an "AS IS" BASIS,
38378  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
38379  * See the License for the specific language governing permissions and
38380  * limitations under the License.
38381  */
38382 
38383 // gen_amalgamated expanded: #include "src/tracing/internal/tracing_muxer_fake.h"
38384 
38385 namespace perfetto {
38386 namespace internal {
38387 namespace {
38388 
FailUninitialized()38389 PERFETTO_NORETURN void FailUninitialized() {
38390   PERFETTO_FATAL(
38391       "Tracing not initialized. Call perfetto::Tracing::Initialize() first.");
38392 }
38393 
38394 }  // namespace
38395 
38396 #if PERFETTO_HAS_NO_DESTROY()
38397 // static
38398 PERFETTO_NO_DESTROY TracingMuxerFake::FakePlatform
38399     TracingMuxerFake::FakePlatform::instance{};
38400 // static
38401 PERFETTO_NO_DESTROY TracingMuxerFake TracingMuxerFake::instance{};
38402 #endif  // PERFETTO_HAS_NO_DESTROY()
38403 
38404 TracingMuxerFake::FakePlatform::~FakePlatform() = default;
38405 
38406 Platform::ThreadLocalObject*
GetOrCreateThreadLocalObject()38407 TracingMuxerFake::FakePlatform::GetOrCreateThreadLocalObject() {
38408   FailUninitialized();
38409 }
38410 
38411 std::unique_ptr<base::TaskRunner>
CreateTaskRunner(const CreateTaskRunnerArgs &)38412 TracingMuxerFake::FakePlatform::CreateTaskRunner(const CreateTaskRunnerArgs&) {
38413   FailUninitialized();
38414 }
38415 
GetCurrentProcessName()38416 std::string TracingMuxerFake::FakePlatform::GetCurrentProcessName() {
38417   FailUninitialized();
38418 }
38419 
RegisterDataSource(const DataSourceDescriptor &,DataSourceFactory,DataSourceStaticState *)38420 bool TracingMuxerFake::RegisterDataSource(const DataSourceDescriptor&,
38421                                           DataSourceFactory,
38422                                           DataSourceStaticState*) {
38423   FailUninitialized();
38424 }
38425 
CreateTraceWriter(DataSourceStaticState *,uint32_t,DataSourceState *,BufferExhaustedPolicy)38426 std::unique_ptr<TraceWriterBase> TracingMuxerFake::CreateTraceWriter(
38427     DataSourceStaticState*,
38428     uint32_t,
38429     DataSourceState*,
38430     BufferExhaustedPolicy) {
38431   FailUninitialized();
38432 }
38433 
DestroyStoppedTraceWritersForCurrentThread()38434 void TracingMuxerFake::DestroyStoppedTraceWritersForCurrentThread() {
38435   FailUninitialized();
38436 }
38437 
RegisterInterceptor(const InterceptorDescriptor &,InterceptorFactory,InterceptorBase::TLSFactory,InterceptorBase::TracePacketCallback)38438 void TracingMuxerFake::RegisterInterceptor(
38439     const InterceptorDescriptor&,
38440     InterceptorFactory,
38441     InterceptorBase::TLSFactory,
38442     InterceptorBase::TracePacketCallback) {
38443   FailUninitialized();
38444 }
38445 
38446 }  // namespace internal
38447 }  // namespace perfetto
38448 // gen_amalgamated begin source: src/tracing/internal/tracing_muxer_impl.cc
38449 // gen_amalgamated begin header: src/tracing/internal/tracing_muxer_impl.h
38450 /*
38451  * Copyright (C) 2019 The Android Open Source Project
38452  *
38453  * Licensed under the Apache License, Version 2.0 (the "License");
38454  * you may not use this file except in compliance with the License.
38455  * You may obtain a copy of the License at
38456  *
38457  *      http://www.apache.org/licenses/LICENSE-2.0
38458  *
38459  * Unless required by applicable law or agreed to in writing, software
38460  * distributed under the License is distributed on an "AS IS" BASIS,
38461  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
38462  * See the License for the specific language governing permissions and
38463  * limitations under the License.
38464  */
38465 
38466 #ifndef SRC_TRACING_INTERNAL_TRACING_MUXER_IMPL_H_
38467 #define SRC_TRACING_INTERNAL_TRACING_MUXER_IMPL_H_
38468 
38469 #include <stddef.h>
38470 #include <stdint.h>
38471 
38472 #include <array>
38473 #include <atomic>
38474 #include <bitset>
38475 #include <list>
38476 #include <map>
38477 #include <memory>
38478 #include <vector>
38479 
38480 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
38481 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
38482 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
38483 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
38484 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
38485 // gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
38486 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
38487 // gen_amalgamated expanded: #include "perfetto/tracing/core/trace_config.h"
38488 // gen_amalgamated expanded: #include "perfetto/tracing/internal/basic_types.h"
38489 // gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_muxer.h"
38490 // gen_amalgamated expanded: #include "perfetto/tracing/tracing.h"
38491 
38492 // gen_amalgamated expanded: #include "protos/perfetto/common/interceptor_descriptor.gen.h"
38493 
38494 namespace perfetto {
38495 
38496 class ConsumerEndpoint;
38497 class DataSourceBase;
38498 class ProducerEndpoint;
38499 class TraceWriterBase;
38500 class TracingBackend;
38501 class TracingSession;
38502 struct TracingInitArgs;
38503 
38504 namespace base {
38505 class TaskRunner;
38506 }
38507 
38508 namespace internal {
38509 
38510 struct DataSourceStaticState;
38511 
38512 // This class acts as a bridge between the public API and the TracingBackend(s).
38513 // It exposes a simplified view of the world to the API methods handling all the
38514 // bookkeeping to map data source instances and trace writers to the various
38515 // backends. It deals with N data sources, M backends (1 backend == 1 tracing
38516 // service == 1 producer connection) and T concurrent tracing sessions.
38517 //
38518 // Handing data source registration and start/stop flows [producer side]:
38519 // ----------------------------------------------------------------------
38520 // 1. The API client subclasses perfetto::DataSource and calls
38521 //    DataSource::Register<MyDataSource>(). In turn this calls into the
38522 //    TracingMuxer.
38523 // 2. The tracing muxer iterates through all the backends (1 backend == 1
38524 //    service == 1 producer connection) and registers the data source on each
38525 //    backend.
38526 // 3. When any (services behind a) backend starts tracing and requests to start
38527 //    that specific data source, the TracingMuxerImpl constructs a new instance
38528 //    of MyDataSource and calls the OnStart() method.
38529 //
38530 // Controlling trace and retrieving trace data [consumer side]:
38531 // ------------------------------------------------------------
38532 // 1. The API client calls Tracing::NewTrace(), returns a RAII TracingSession
38533 //    object.
38534 // 2. NewTrace() calls into internal::TracingMuxer(Impl). TracingMuxer
38535 //    subclasses the TracingSession object (TracingSessionImpl) and returns it.
38536 // 3. The tracing muxer identifies the backend (according to the args passed to
38537 //    NewTrace), creates a new Consumer and connects to it.
38538 // 4. When the API client calls Start()/Stop()/ReadTrace() methods, the
38539 //    TracingMuxer forwards them to the consumer associated to the
38540 //    TracingSession. Likewise for callbacks coming from the consumer-side of
38541 //    the service.
38542 class TracingMuxerImpl : public TracingMuxer {
38543  public:
38544   // This is different than TracingSessionID because it's global across all
38545   // backends. TracingSessionID is global only within the scope of one service.
38546   using TracingSessionGlobalID = uint64_t;
38547 
38548   static void InitializeInstance(const TracingInitArgs&);
38549 
38550   // TracingMuxer implementation.
38551   bool RegisterDataSource(const DataSourceDescriptor&,
38552                           DataSourceFactory,
38553                           DataSourceStaticState*) override;
38554   std::unique_ptr<TraceWriterBase> CreateTraceWriter(
38555       DataSourceStaticState*,
38556       uint32_t data_source_instance_index,
38557       DataSourceState*,
38558       BufferExhaustedPolicy buffer_exhausted_policy) override;
38559   void DestroyStoppedTraceWritersForCurrentThread() override;
38560   void RegisterInterceptor(const InterceptorDescriptor&,
38561                            InterceptorFactory,
38562                            InterceptorBase::TLSFactory,
38563                            InterceptorBase::TracePacketCallback) override;
38564 
38565   std::unique_ptr<TracingSession> CreateTracingSession(BackendType);
38566 
38567   // Producer-side bookkeeping methods.
38568   void UpdateDataSourcesOnAllBackends();
38569   void SetupDataSource(TracingBackendId,
38570                        uint32_t backend_connection_id,
38571                        DataSourceInstanceID,
38572                        const DataSourceConfig&);
38573   void StartDataSource(TracingBackendId, DataSourceInstanceID);
38574   void StopDataSource_AsyncBegin(TracingBackendId, DataSourceInstanceID);
38575   void StopDataSource_AsyncEnd(TracingBackendId, DataSourceInstanceID);
38576   void ClearDataSourceIncrementalState(TracingBackendId, DataSourceInstanceID);
38577   void SyncProducersForTesting();
38578 
38579   // Consumer-side bookkeeping methods.
38580   void SetupTracingSession(TracingSessionGlobalID,
38581                            const std::shared_ptr<TraceConfig>&,
38582                            base::ScopedFile trace_fd = base::ScopedFile());
38583   void StartTracingSession(TracingSessionGlobalID);
38584   void ChangeTracingSessionConfig(TracingSessionGlobalID, const TraceConfig&);
38585   void StopTracingSession(TracingSessionGlobalID);
38586   void DestroyTracingSession(TracingSessionGlobalID);
38587   void FlushTracingSession(TracingSessionGlobalID,
38588                            uint32_t,
38589                            std::function<void(bool)>);
38590   void ReadTracingSessionData(
38591       TracingSessionGlobalID,
38592       std::function<void(TracingSession::ReadTraceCallbackArgs)>);
38593   void GetTraceStats(TracingSessionGlobalID,
38594                      TracingSession::GetTraceStatsCallback);
38595   void QueryServiceState(TracingSessionGlobalID,
38596                          TracingSession::QueryServiceStateCallback);
38597 
38598   // Sets the batching period to |batch_commits_duration_ms| on the backends
38599   // with type |backend_type|.
38600   void SetBatchCommitsDurationForTesting(uint32_t batch_commits_duration_ms,
38601                                          BackendType backend_type);
38602 
38603   // Enables direct SMB patching on the backends with type |backend_type| (see
38604   // SharedMemoryArbiter::EnableDirectSMBPatching). Returns true if the
38605   // operation succeeded for all backends with type |backend_type|, false
38606   // otherwise.
38607   bool EnableDirectSMBPatchingForTesting(BackendType backend_type);
38608 
38609   void SetMaxProducerReconnectionsForTesting(uint32_t count);
38610 
38611  private:
38612   // For each TracingBackend we create and register one ProducerImpl instance.
38613   // This talks to the producer-side of the service, gets start/stop requests
38614   // from it and routes them to the registered data sources.
38615   // One ProducerImpl == one backend == one tracing service.
38616   // This class is needed to disambiguate callbacks coming from different
38617   // services. TracingMuxerImpl can't directly implement the Producer interface
38618   // because the Producer virtual methods don't allow to identify the service.
38619   class ProducerImpl : public Producer {
38620    public:
38621     ProducerImpl(TracingMuxerImpl*,
38622                  TracingBackendId,
38623                  uint32_t shmem_batch_commits_duration_ms);
38624     ~ProducerImpl() override;
38625 
38626     void Initialize(std::unique_ptr<ProducerEndpoint> endpoint);
38627     void RegisterDataSource(const DataSourceDescriptor&,
38628                             DataSourceFactory,
38629                             DataSourceStaticState*);
38630 
38631     // perfetto::Producer implementation.
38632     void OnConnect() override;
38633     void OnDisconnect() override;
38634     void OnTracingSetup() override;
38635     void SetupDataSource(DataSourceInstanceID,
38636                          const DataSourceConfig&) override;
38637     void StartDataSource(DataSourceInstanceID,
38638                          const DataSourceConfig&) override;
38639     void StopDataSource(DataSourceInstanceID) override;
38640     void Flush(FlushRequestID, const DataSourceInstanceID*, size_t) override;
38641     void ClearIncrementalState(const DataSourceInstanceID*, size_t) override;
38642 
38643     void SweepDeadServices();
38644 
38645     PERFETTO_THREAD_CHECKER(thread_checker_)
38646     TracingMuxerImpl* const muxer_;
38647     TracingBackendId const backend_id_;
38648     bool connected_ = false;
38649     uint32_t connection_id_ = 0;
38650 
38651     const uint32_t shmem_batch_commits_duration_ms_ = 0;
38652 
38653     // Set of data sources that have been actually registered on this producer.
38654     // This can be a subset of the global |data_sources_|, because data sources
38655     // can register before the producer is fully connected.
38656     std::bitset<kMaxDataSources> registered_data_sources_{};
38657 
38658     // A collection of disconnected service endpoints. Since trace writers on
38659     // arbitrary threads might continue writing data to disconnected services,
38660     // we keep the old services around and periodically try to clean up ones
38661     // that no longer have any writers (see SweepDeadServices).
38662     std::list<std::shared_ptr<ProducerEndpoint>> dead_services_;
38663 
38664     // The currently active service endpoint is maintained as an atomic shared
38665     // pointer so it won't get deleted from underneath threads that are creating
38666     // trace writers. At any given time one endpoint can be shared (and thus
38667     // kept alive) by the |service_| pointer, an entry in |dead_services_| and
38668     // as a pointer on the stack in CreateTraceWriter() (on an arbitrary
38669     // thread). The endpoint is never shared outside ProducerImpl itself.
38670     //
38671     // WARNING: Any *write* access to this variable or any *read* access from a
38672     // non-muxer thread must be done through std::atomic_{load,store} to avoid
38673     // data races.
38674     std::shared_ptr<ProducerEndpoint> service_;  // Keep last.
38675   };
38676 
38677   // For each TracingSession created by the API client (Tracing::NewTrace() we
38678   // create and register one ConsumerImpl instance.
38679   // This talks to the consumer-side of the service, gets end-of-trace and
38680   // on-trace-data callbacks and routes them to the API client callbacks.
38681   // This class is needed to disambiguate callbacks coming from different
38682   // tracing sessions.
38683   class ConsumerImpl : public Consumer {
38684    public:
38685     ConsumerImpl(TracingMuxerImpl*,
38686                  BackendType,
38687                  TracingBackendId,
38688                  TracingSessionGlobalID);
38689     ~ConsumerImpl() override;
38690 
38691     void Initialize(std::unique_ptr<ConsumerEndpoint> endpoint);
38692 
38693     // perfetto::Consumer implementation.
38694     void OnConnect() override;
38695     void OnDisconnect() override;
38696     void OnTracingDisabled(const std::string& error) override;
38697     void OnTraceData(std::vector<TracePacket>, bool has_more) override;
38698     void OnDetach(bool success) override;
38699     void OnAttach(bool success, const TraceConfig&) override;
38700     void OnTraceStats(bool success, const TraceStats&) override;
38701     void OnObservableEvents(const ObservableEvents&) override;
38702 
38703     void NotifyStartComplete();
38704     void NotifyError(const TracingError&);
38705     void NotifyStopComplete();
38706 
38707     // Will eventually inform the |muxer_| when it is safe to remove |this|.
38708     void Disconnect();
38709 
38710     TracingMuxerImpl* const muxer_;
38711     BackendType const backend_type_;
38712     TracingBackendId const backend_id_;
38713     TracingSessionGlobalID const session_id_;
38714     bool connected_ = false;
38715 
38716     // This is to handle the case where the Setup call from the API client
38717     // arrives before the consumer has connected. In this case we keep around
38718     // the config and check if we have it after connection.
38719     bool start_pending_ = false;
38720 
38721     // Similarly if the session is stopped before the consumer was connected, we
38722     // need to wait until the session has started before stopping it.
38723     bool stop_pending_ = false;
38724 
38725     // Similarly we need to buffer a call to get trace statistics if the
38726     // consumer wasn't connected yet.
38727     bool get_trace_stats_pending_ = false;
38728 
38729     // Whether this session was already stopped. This will happen in response to
38730     // Stop{,Blocking}, but also if the service stops the session for us
38731     // automatically (e.g., when there are no data sources).
38732     bool stopped_ = false;
38733 
38734     // shared_ptr because it's posted across threads. This is to avoid copying
38735     // it more than once.
38736     std::shared_ptr<TraceConfig> trace_config_;
38737     base::ScopedFile trace_fd_;
38738 
38739     // If the API client passes a callback to start, we should invoke this when
38740     // NotifyStartComplete() is invoked.
38741     std::function<void()> start_complete_callback_;
38742 
38743     // An internal callback used to implement StartBlocking().
38744     std::function<void()> blocking_start_complete_callback_;
38745 
38746     // If the API client passes a callback to get notification about the
38747     // errors, we should invoke this when NotifyError() is invoked.
38748     std::function<void(TracingError)> error_callback_;
38749 
38750     // If the API client passes a callback to stop, we should invoke this when
38751     // OnTracingDisabled() is invoked.
38752     std::function<void()> stop_complete_callback_;
38753 
38754     // An internal callback used to implement StopBlocking().
38755     std::function<void()> blocking_stop_complete_callback_;
38756 
38757     // Callback passed to ReadTrace().
38758     std::function<void(TracingSession::ReadTraceCallbackArgs)>
38759         read_trace_callback_;
38760 
38761     // Callback passed to GetTraceStats().
38762     TracingSession::GetTraceStatsCallback get_trace_stats_callback_;
38763 
38764     // Callback for a pending call to QueryServiceState().
38765     TracingSession::QueryServiceStateCallback query_service_state_callback_;
38766 
38767     // The states of all data sources in this tracing session. |true| means the
38768     // data source has started tracing.
38769     using DataSourceHandle = std::pair<std::string, std::string>;
38770     std::map<DataSourceHandle, bool> data_source_states_;
38771 
38772     std::unique_ptr<ConsumerEndpoint> service_;  // Keep before last.
38773     PERFETTO_THREAD_CHECKER(thread_checker_)     // Keep last.
38774   };
38775 
38776   // This object is returned to API clients when they call
38777   // Tracing::CreateTracingSession().
38778   class TracingSessionImpl : public TracingSession {
38779    public:
38780     TracingSessionImpl(TracingMuxerImpl*, TracingSessionGlobalID, BackendType);
38781     ~TracingSessionImpl() override;
38782     void Setup(const TraceConfig&, int fd) override;
38783     void Start() override;
38784     void StartBlocking() override;
38785     void SetOnStartCallback(std::function<void()>) override;
38786     void SetOnErrorCallback(std::function<void(TracingError)>) override;
38787     void Stop() override;
38788     void StopBlocking() override;
38789     void Flush(std::function<void(bool)>, uint32_t timeout_ms) override;
38790     void ReadTrace(ReadTraceCallback) override;
38791     void SetOnStopCallback(std::function<void()>) override;
38792     void GetTraceStats(GetTraceStatsCallback) override;
38793     void QueryServiceState(QueryServiceStateCallback) override;
38794     void ChangeTraceConfig(const TraceConfig&) override;
38795 
38796    private:
38797     TracingMuxerImpl* const muxer_;
38798     TracingSessionGlobalID const session_id_;
38799     BackendType const backend_type_;
38800   };
38801 
38802   struct RegisteredDataSource {
38803     DataSourceDescriptor descriptor;
38804     DataSourceFactory factory{};
38805     DataSourceStaticState* static_state = nullptr;
38806   };
38807 
38808   struct RegisteredInterceptor {
38809     protos::gen::InterceptorDescriptor descriptor;
38810     InterceptorFactory factory{};
38811     InterceptorBase::TLSFactory tls_factory{};
38812     InterceptorBase::TracePacketCallback packet_callback{};
38813   };
38814 
38815   struct RegisteredBackend {
38816     // Backends are supposed to have static lifetime.
38817     TracingBackend* backend = nullptr;
38818     TracingBackendId id = 0;
38819     BackendType type{};
38820 
38821     TracingBackend::ConnectProducerArgs producer_conn_args;
38822     std::unique_ptr<ProducerImpl> producer;
38823 
38824     // The calling code can request more than one concurrently active tracing
38825     // session for the same backend. We need to create one consumer per session.
38826     std::vector<std::unique_ptr<ConsumerImpl>> consumers;
38827   };
38828 
38829   explicit TracingMuxerImpl(const TracingInitArgs&);
38830   void Initialize(const TracingInitArgs& args);
38831   ConsumerImpl* FindConsumer(TracingSessionGlobalID session_id);
38832   void InitializeConsumer(TracingSessionGlobalID session_id);
38833   void OnConsumerDisconnected(ConsumerImpl* consumer);
38834   void OnProducerDisconnected(ProducerImpl* producer);
38835 
38836   struct FindDataSourceRes {
38837     FindDataSourceRes() = default;
FindDataSourceResperfetto::internal::TracingMuxerImpl::FindDataSourceRes38838     FindDataSourceRes(DataSourceStaticState* a, DataSourceState* b, uint32_t c)
38839         : static_state(a), internal_state(b), instance_idx(c) {}
operator boolperfetto::internal::TracingMuxerImpl::FindDataSourceRes38840     explicit operator bool() const { return !!internal_state; }
38841 
38842     DataSourceStaticState* static_state = nullptr;
38843     DataSourceState* internal_state = nullptr;
38844     uint32_t instance_idx = 0;
38845   };
38846   FindDataSourceRes FindDataSource(TracingBackendId, DataSourceInstanceID);
38847 
38848   std::unique_ptr<base::TaskRunner> task_runner_;
38849   std::vector<RegisteredDataSource> data_sources_;
38850   std::vector<RegisteredBackend> backends_;
38851   std::vector<RegisteredInterceptor> interceptors_;
38852   TracingPolicy* policy_ = nullptr;
38853 
38854   std::atomic<TracingSessionGlobalID> next_tracing_session_id_{};
38855 
38856   // Maximum number of times we will try to reconnect producer backend.
38857   // Should only be modified for testing purposes.
38858   std::atomic<uint32_t> max_producer_reconnections_{100u};
38859 
38860   PERFETTO_THREAD_CHECKER(thread_checker_)
38861 };
38862 
38863 }  // namespace internal
38864 }  // namespace perfetto
38865 
38866 #endif  // SRC_TRACING_INTERNAL_TRACING_MUXER_IMPL_H_
38867 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/trace_stats.h
38868 /*
38869  * Copyright (C) 2017 The Android Open Source Project
38870  *
38871  * Licensed under the Apache License, Version 2.0 (the "License");
38872  * you may not use this file except in compliance with the License.
38873  * You may obtain a copy of the License at
38874  *
38875  *      http://www.apache.org/licenses/LICENSE-2.0
38876  *
38877  * Unless required by applicable law or agreed to in writing, software
38878  * distributed under the License is distributed on an "AS IS" BASIS,
38879  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
38880  * See the License for the specific language governing permissions and
38881  * limitations under the License.
38882  */
38883 
38884 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_STATS_H_
38885 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_STATS_H_
38886 
38887 // Creates the aliases in the ::perfetto namespace, doing things like:
38888 // using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
38889 // See comments in forward_decls.h for the historical reasons of this
38890 // indirection layer.
38891 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
38892 
38893 // gen_amalgamated expanded: #include "protos/perfetto/common/trace_stats.gen.h"
38894 
38895 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_STATS_H_
38896 // gen_amalgamated begin header: include/perfetto/tracing/core/tracing_service_state.h
38897 /*
38898  * Copyright (C) 2017 The Android Open Source Project
38899  *
38900  * Licensed under the Apache License, Version 2.0 (the "License");
38901  * you may not use this file except in compliance with the License.
38902  * You may obtain a copy of the License at
38903  *
38904  *      http://www.apache.org/licenses/LICENSE-2.0
38905  *
38906  * Unless required by applicable law or agreed to in writing, software
38907  * distributed under the License is distributed on an "AS IS" BASIS,
38908  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
38909  * See the License for the specific language governing permissions and
38910  * limitations under the License.
38911  */
38912 
38913 
38914 #ifndef INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_STATE_H_
38915 #define INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_STATE_H_
38916 
38917 // Creates the aliases in the ::perfetto namespace, doing things like:
38918 // using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
38919 // See comments in forward_decls.h for the historical reasons of this
38920 // indirection layer.
38921 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
38922 
38923 // gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_state.gen.h"
38924 
38925 #endif  // INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_STATE_H_
38926 /*
38927  * Copyright (C) 2019 The Android Open Source Project
38928  *
38929  * Licensed under the Apache License, Version 2.0 (the "License");
38930  * you may not use this file except in compliance with the License.
38931  * You may obtain a copy of the License at
38932  *
38933  *      http://www.apache.org/licenses/LICENSE-2.0
38934  *
38935  * Unless required by applicable law or agreed to in writing, software
38936  * distributed under the License is distributed on an "AS IS" BASIS,
38937  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
38938  * See the License for the specific language governing permissions and
38939  * limitations under the License.
38940  */
38941 
38942 // gen_amalgamated expanded: #include "src/tracing/internal/tracing_muxer_impl.h"
38943 
38944 #include <algorithm>
38945 #include <atomic>
38946 #include <mutex>
38947 #include <vector>
38948 
38949 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
38950 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
38951 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
38952 // gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
38953 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
38954 // gen_amalgamated expanded: #include "perfetto/ext/base/waitable_event.h"
38955 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
38956 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
38957 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_stats.h"
38958 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
38959 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
38960 // gen_amalgamated expanded: #include "perfetto/tracing/buffer_exhausted_policy.h"
38961 // gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
38962 // gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_state.h"
38963 // gen_amalgamated expanded: #include "perfetto/tracing/data_source.h"
38964 // gen_amalgamated expanded: #include "perfetto/tracing/internal/data_source_internal.h"
38965 // gen_amalgamated expanded: #include "perfetto/tracing/internal/interceptor_trace_writer.h"
38966 // gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_backend_fake.h"
38967 // gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
38968 // gen_amalgamated expanded: #include "perfetto/tracing/tracing.h"
38969 // gen_amalgamated expanded: #include "perfetto/tracing/tracing_backend.h"
38970 
38971 // gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
38972 
38973 // gen_amalgamated expanded: #include "src/tracing/internal/tracing_muxer_fake.h"
38974 
38975 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
38976 #include <io.h>  // For dup()
38977 #else
38978 #include <unistd.h>  // For dup()
38979 #endif
38980 
38981 namespace perfetto {
38982 namespace internal {
38983 
38984 namespace {
38985 
38986 // A task runner which prevents calls to DataSource::Trace() while an operation
38987 // is in progress. Used to guard against unexpected re-entrancy where the
38988 // user-provided task runner implementation tries to enter a trace point under
38989 // the hood.
38990 class NonReentrantTaskRunner : public base::TaskRunner {
38991  public:
NonReentrantTaskRunner(TracingMuxer * muxer,std::unique_ptr<base::TaskRunner> task_runner)38992   NonReentrantTaskRunner(TracingMuxer* muxer,
38993                          std::unique_ptr<base::TaskRunner> task_runner)
38994       : muxer_(muxer), task_runner_(std::move(task_runner)) {}
38995 
38996   // base::TaskRunner implementation.
PostTask(std::function<void ()> task)38997   void PostTask(std::function<void()> task) override {
38998     CallWithGuard([&] { task_runner_->PostTask(std::move(task)); });
38999   }
39000 
PostDelayedTask(std::function<void ()> task,uint32_t delay_ms)39001   void PostDelayedTask(std::function<void()> task, uint32_t delay_ms) override {
39002     CallWithGuard(
39003         [&] { task_runner_->PostDelayedTask(std::move(task), delay_ms); });
39004   }
39005 
AddFileDescriptorWatch(base::PlatformHandle fd,std::function<void ()> callback)39006   void AddFileDescriptorWatch(base::PlatformHandle fd,
39007                               std::function<void()> callback) override {
39008     CallWithGuard(
39009         [&] { task_runner_->AddFileDescriptorWatch(fd, std::move(callback)); });
39010   }
39011 
RemoveFileDescriptorWatch(base::PlatformHandle fd)39012   void RemoveFileDescriptorWatch(base::PlatformHandle fd) override {
39013     CallWithGuard([&] { task_runner_->RemoveFileDescriptorWatch(fd); });
39014   }
39015 
RunsTasksOnCurrentThread() const39016   bool RunsTasksOnCurrentThread() const override {
39017     bool result;
39018     CallWithGuard([&] { result = task_runner_->RunsTasksOnCurrentThread(); });
39019     return result;
39020   }
39021 
39022  private:
39023   template <typename T>
CallWithGuard(T lambda) const39024   void CallWithGuard(T lambda) const {
39025     auto* root_tls = muxer_->GetOrCreateTracingTLS();
39026     if (PERFETTO_UNLIKELY(root_tls->is_in_trace_point)) {
39027       lambda();
39028       return;
39029     }
39030     ScopedReentrancyAnnotator scoped_annotator(*root_tls);
39031     lambda();
39032   }
39033 
39034   TracingMuxer* const muxer_;
39035   std::unique_ptr<base::TaskRunner> task_runner_;
39036 };
39037 
39038 class StopArgsImpl : public DataSourceBase::StopArgs {
39039  public:
HandleStopAsynchronously() const39040   std::function<void()> HandleStopAsynchronously() const override {
39041     auto closure = std::move(async_stop_closure);
39042     async_stop_closure = std::function<void()>();
39043     return closure;
39044   }
39045 
39046   mutable std::function<void()> async_stop_closure;
39047 };
39048 
ComputeConfigHash(const DataSourceConfig & config)39049 uint64_t ComputeConfigHash(const DataSourceConfig& config) {
39050   base::Hash hasher;
39051   std::string config_bytes = config.SerializeAsString();
39052   hasher.Update(config_bytes.data(), config_bytes.size());
39053   return hasher.digest();
39054 }
39055 
39056 }  // namespace
39057 
39058 // ----- Begin of TracingMuxerImpl::ProducerImpl
ProducerImpl(TracingMuxerImpl * muxer,TracingBackendId backend_id,uint32_t shmem_batch_commits_duration_ms)39059 TracingMuxerImpl::ProducerImpl::ProducerImpl(
39060     TracingMuxerImpl* muxer,
39061     TracingBackendId backend_id,
39062     uint32_t shmem_batch_commits_duration_ms)
39063     : muxer_(muxer),
39064       backend_id_(backend_id),
39065       shmem_batch_commits_duration_ms_(shmem_batch_commits_duration_ms) {}
39066 
39067 TracingMuxerImpl::ProducerImpl::~ProducerImpl() = default;
39068 
Initialize(std::unique_ptr<ProducerEndpoint> endpoint)39069 void TracingMuxerImpl::ProducerImpl::Initialize(
39070     std::unique_ptr<ProducerEndpoint> endpoint) {
39071   PERFETTO_DCHECK_THREAD(thread_checker_);
39072   PERFETTO_DCHECK(!connected_);
39073   connection_id_++;
39074 
39075   // Adopt the endpoint into a shared pointer so that we can safely share it
39076   // across threads that create trace writers. The custom deleter function
39077   // ensures that the endpoint is always destroyed on the muxer's thread. (Note
39078   // that |task_runner| is assumed to outlive tracing sessions on all threads.)
39079   auto* task_runner = muxer_->task_runner_.get();
39080   auto deleter = [task_runner](ProducerEndpoint* e) {
39081     task_runner->PostTask([e] { delete e; });
39082   };
39083   std::shared_ptr<ProducerEndpoint> service(endpoint.release(), deleter);
39084   // This atomic store is needed because another thread might be concurrently
39085   // creating a trace writer using the previous (disconnected) |service_|. See
39086   // CreateTraceWriter().
39087   std::atomic_store(&service_, std::move(service));
39088   // Don't try to use the service here since it may not have connected yet. See
39089   // OnConnect().
39090 }
39091 
OnConnect()39092 void TracingMuxerImpl::ProducerImpl::OnConnect() {
39093   PERFETTO_DLOG("Producer connected");
39094   PERFETTO_DCHECK_THREAD(thread_checker_);
39095   PERFETTO_DCHECK(!connected_);
39096   connected_ = true;
39097   muxer_->UpdateDataSourcesOnAllBackends();
39098 }
39099 
OnDisconnect()39100 void TracingMuxerImpl::ProducerImpl::OnDisconnect() {
39101   PERFETTO_DCHECK_THREAD(thread_checker_);
39102   connected_ = false;
39103   // Active data sources for this producer will be stopped by
39104   // DestroyStoppedTraceWritersForCurrentThread() since the reconnected producer
39105   // will have a different connection id (even before it has finished
39106   // connecting).
39107   registered_data_sources_.reset();
39108   // Keep the old service around as a dead connection in case it has active
39109   // trace writers. We can't clear |service_| here because other threads may be
39110   // concurrently creating new trace writers. The reconnection below will
39111   // atomically swap the new service in place of the old one.
39112   dead_services_.push_back(service_);
39113   // Try reconnecting the producer.
39114   muxer_->OnProducerDisconnected(this);
39115 }
39116 
OnTracingSetup()39117 void TracingMuxerImpl::ProducerImpl::OnTracingSetup() {
39118   PERFETTO_DCHECK_THREAD(thread_checker_);
39119   service_->MaybeSharedMemoryArbiter()->SetBatchCommitsDuration(
39120       shmem_batch_commits_duration_ms_);
39121 }
39122 
SetupDataSource(DataSourceInstanceID id,const DataSourceConfig & cfg)39123 void TracingMuxerImpl::ProducerImpl::SetupDataSource(
39124     DataSourceInstanceID id,
39125     const DataSourceConfig& cfg) {
39126   PERFETTO_DCHECK_THREAD(thread_checker_);
39127   muxer_->SetupDataSource(backend_id_, connection_id_, id, cfg);
39128 }
39129 
StartDataSource(DataSourceInstanceID id,const DataSourceConfig &)39130 void TracingMuxerImpl::ProducerImpl::StartDataSource(DataSourceInstanceID id,
39131                                                      const DataSourceConfig&) {
39132   PERFETTO_DCHECK_THREAD(thread_checker_);
39133   muxer_->StartDataSource(backend_id_, id);
39134   service_->NotifyDataSourceStarted(id);
39135 }
39136 
StopDataSource(DataSourceInstanceID id)39137 void TracingMuxerImpl::ProducerImpl::StopDataSource(DataSourceInstanceID id) {
39138   PERFETTO_DCHECK_THREAD(thread_checker_);
39139   muxer_->StopDataSource_AsyncBegin(backend_id_, id);
39140 }
39141 
Flush(FlushRequestID flush_id,const DataSourceInstanceID *,size_t)39142 void TracingMuxerImpl::ProducerImpl::Flush(FlushRequestID flush_id,
39143                                            const DataSourceInstanceID*,
39144                                            size_t) {
39145   // Flush is not plumbed for now, we just ack straight away.
39146   PERFETTO_DCHECK_THREAD(thread_checker_);
39147   service_->NotifyFlushComplete(flush_id);
39148 }
39149 
ClearIncrementalState(const DataSourceInstanceID * instances,size_t instance_count)39150 void TracingMuxerImpl::ProducerImpl::ClearIncrementalState(
39151     const DataSourceInstanceID* instances,
39152     size_t instance_count) {
39153   PERFETTO_DCHECK_THREAD(thread_checker_);
39154   for (size_t inst_idx = 0; inst_idx < instance_count; inst_idx++) {
39155     muxer_->ClearDataSourceIncrementalState(backend_id_, instances[inst_idx]);
39156   }
39157 }
39158 
SweepDeadServices()39159 void TracingMuxerImpl::ProducerImpl::SweepDeadServices() {
39160   PERFETTO_DCHECK_THREAD(thread_checker_);
39161   auto is_unused = [](const std::shared_ptr<ProducerEndpoint>& endpoint) {
39162     auto* arbiter = endpoint->MaybeSharedMemoryArbiter();
39163     return !arbiter || arbiter->TryShutdown();
39164   };
39165   for (auto it = dead_services_.begin(); it != dead_services_.end();) {
39166     auto next_it = it;
39167     next_it++;
39168     if (is_unused(*it)) {
39169       dead_services_.erase(it);
39170     }
39171     it = next_it;
39172   }
39173 }
39174 
39175 // ----- End of TracingMuxerImpl::ProducerImpl methods.
39176 
39177 // ----- Begin of TracingMuxerImpl::ConsumerImpl
ConsumerImpl(TracingMuxerImpl * muxer,BackendType backend_type,TracingBackendId backend_id,TracingSessionGlobalID session_id)39178 TracingMuxerImpl::ConsumerImpl::ConsumerImpl(TracingMuxerImpl* muxer,
39179                                              BackendType backend_type,
39180                                              TracingBackendId backend_id,
39181                                              TracingSessionGlobalID session_id)
39182     : muxer_(muxer),
39183       backend_type_(backend_type),
39184       backend_id_(backend_id),
39185       session_id_(session_id) {}
39186 
39187 TracingMuxerImpl::ConsumerImpl::~ConsumerImpl() = default;
39188 
Initialize(std::unique_ptr<ConsumerEndpoint> endpoint)39189 void TracingMuxerImpl::ConsumerImpl::Initialize(
39190     std::unique_ptr<ConsumerEndpoint> endpoint) {
39191   PERFETTO_DCHECK_THREAD(thread_checker_);
39192   service_ = std::move(endpoint);
39193   // Don't try to use the service here since it may not have connected yet. See
39194   // OnConnect().
39195 }
39196 
OnConnect()39197 void TracingMuxerImpl::ConsumerImpl::OnConnect() {
39198   PERFETTO_DCHECK_THREAD(thread_checker_);
39199   PERFETTO_DCHECK(!connected_);
39200   connected_ = true;
39201 
39202   // Observe data source instance events so we get notified when tracing starts.
39203   service_->ObserveEvents(ObservableEvents::TYPE_DATA_SOURCES_INSTANCES |
39204                           ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED);
39205 
39206   // If the API client configured and started tracing before we connected,
39207   // tell the backend about it now.
39208   if (trace_config_)
39209     muxer_->SetupTracingSession(session_id_, trace_config_);
39210   if (start_pending_)
39211     muxer_->StartTracingSession(session_id_);
39212   if (get_trace_stats_pending_) {
39213     auto callback = std::move(get_trace_stats_callback_);
39214     get_trace_stats_callback_ = nullptr;
39215     muxer_->GetTraceStats(session_id_, std::move(callback));
39216   }
39217   if (query_service_state_callback_) {
39218     auto callback = std::move(query_service_state_callback_);
39219     query_service_state_callback_ = nullptr;
39220     muxer_->QueryServiceState(session_id_, std::move(callback));
39221   }
39222   if (stop_pending_)
39223     muxer_->StopTracingSession(session_id_);
39224 }
39225 
OnDisconnect()39226 void TracingMuxerImpl::ConsumerImpl::OnDisconnect() {
39227   PERFETTO_DCHECK_THREAD(thread_checker_);
39228 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
39229   if (!connected_ && backend_type_ == kSystemBackend) {
39230     PERFETTO_ELOG(
39231         "Unable to connect to the system tracing service as a consumer. On "
39232         "Android, use the \"perfetto\" command line tool instead to start "
39233         "system-wide tracing sessions");
39234   }
39235 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
39236 
39237   // Notify the client about disconnection.
39238   NotifyError(TracingError{TracingError::kDisconnected, "Peer disconnected"});
39239 
39240   // Make sure the client doesn't hang in a blocking start/stop because of the
39241   // disconnection.
39242   NotifyStartComplete();
39243   NotifyStopComplete();
39244 
39245   // It shouldn't be necessary to call StopTracingSession. If we get this call
39246   // it means that the service did shutdown before us, so there is no point
39247   // trying it to ask it to stop the session. We should just remember to cleanup
39248   // the consumer vector.
39249   connected_ = false;
39250 
39251   // Notify the muxer that it is safe to destroy |this|. This is needed because
39252   // the ConsumerEndpoint stored in |service_| requires that |this| be safe to
39253   // access until OnDisconnect() is called.
39254   muxer_->OnConsumerDisconnected(this);
39255 }
39256 
Disconnect()39257 void TracingMuxerImpl::ConsumerImpl::Disconnect() {
39258   // This is weird and deserves a comment.
39259   //
39260   // When we called the ConnectConsumer method on the service it returns
39261   // us a ConsumerEndpoint which we stored in |service_|, however this
39262   // ConsumerEndpoint holds a pointer to the ConsumerImpl pointed to by
39263   // |this|. Part of the API contract to TracingService::ConnectConsumer is that
39264   // the ConsumerImpl pointer has to be valid until the
39265   // ConsumerImpl::OnDisconnect method is called. Therefore we reset the
39266   // ConsumerEndpoint |service_|. Eventually this will call
39267   // ConsumerImpl::OnDisconnect and we will inform the muxer it is safe to
39268   // call the destructor of |this|.
39269   service_.reset();
39270 }
39271 
OnTracingDisabled(const std::string & error)39272 void TracingMuxerImpl::ConsumerImpl::OnTracingDisabled(
39273     const std::string& error) {
39274   PERFETTO_DCHECK_THREAD(thread_checker_);
39275   PERFETTO_DCHECK(!stopped_);
39276   stopped_ = true;
39277 
39278   if (!error.empty())
39279     NotifyError(TracingError{TracingError::kTracingFailed, error});
39280 
39281   // If we're still waiting for the start event, fire it now. This may happen if
39282   // there are no active data sources in the session.
39283   NotifyStartComplete();
39284   NotifyStopComplete();
39285 }
39286 
NotifyStartComplete()39287 void TracingMuxerImpl::ConsumerImpl::NotifyStartComplete() {
39288   PERFETTO_DCHECK_THREAD(thread_checker_);
39289   if (start_complete_callback_) {
39290     muxer_->task_runner_->PostTask(std::move(start_complete_callback_));
39291     start_complete_callback_ = nullptr;
39292   }
39293   if (blocking_start_complete_callback_) {
39294     muxer_->task_runner_->PostTask(
39295         std::move(blocking_start_complete_callback_));
39296     blocking_start_complete_callback_ = nullptr;
39297   }
39298 }
39299 
NotifyError(const TracingError & error)39300 void TracingMuxerImpl::ConsumerImpl::NotifyError(const TracingError& error) {
39301   PERFETTO_DCHECK_THREAD(thread_checker_);
39302   if (error_callback_) {
39303     muxer_->task_runner_->PostTask(
39304         std::bind(std::move(error_callback_), error));
39305   }
39306 }
39307 
NotifyStopComplete()39308 void TracingMuxerImpl::ConsumerImpl::NotifyStopComplete() {
39309   PERFETTO_DCHECK_THREAD(thread_checker_);
39310   if (stop_complete_callback_) {
39311     muxer_->task_runner_->PostTask(std::move(stop_complete_callback_));
39312     stop_complete_callback_ = nullptr;
39313   }
39314   if (blocking_stop_complete_callback_) {
39315     muxer_->task_runner_->PostTask(std::move(blocking_stop_complete_callback_));
39316     blocking_stop_complete_callback_ = nullptr;
39317   }
39318 }
39319 
OnTraceData(std::vector<TracePacket> packets,bool has_more)39320 void TracingMuxerImpl::ConsumerImpl::OnTraceData(
39321     std::vector<TracePacket> packets,
39322     bool has_more) {
39323   PERFETTO_DCHECK_THREAD(thread_checker_);
39324   if (!read_trace_callback_)
39325     return;
39326 
39327   size_t capacity = 0;
39328   for (const auto& packet : packets) {
39329     // 16 is an over-estimation of the proto preamble size
39330     capacity += packet.size() + 16;
39331   }
39332 
39333   // The shared_ptr is to avoid making a copy of the buffer when PostTask-ing.
39334   std::shared_ptr<std::vector<char>> buf(new std::vector<char>());
39335   buf->reserve(capacity);
39336   for (auto& packet : packets) {
39337     char* start;
39338     size_t size;
39339     std::tie(start, size) = packet.GetProtoPreamble();
39340     buf->insert(buf->end(), start, start + size);
39341     for (auto& slice : packet.slices()) {
39342       const auto* slice_data = reinterpret_cast<const char*>(slice.start);
39343       buf->insert(buf->end(), slice_data, slice_data + slice.size);
39344     }
39345   }
39346 
39347   auto callback = read_trace_callback_;
39348   muxer_->task_runner_->PostTask([callback, buf, has_more] {
39349     TracingSession::ReadTraceCallbackArgs callback_arg{};
39350     callback_arg.data = buf->empty() ? nullptr : &(*buf)[0];
39351     callback_arg.size = buf->size();
39352     callback_arg.has_more = has_more;
39353     callback(callback_arg);
39354   });
39355 
39356   if (!has_more)
39357     read_trace_callback_ = nullptr;
39358 }
39359 
OnObservableEvents(const ObservableEvents & events)39360 void TracingMuxerImpl::ConsumerImpl::OnObservableEvents(
39361     const ObservableEvents& events) {
39362   if (events.instance_state_changes_size()) {
39363     for (const auto& state_change : events.instance_state_changes()) {
39364       DataSourceHandle handle{state_change.producer_name(),
39365                               state_change.data_source_name()};
39366       data_source_states_[handle] =
39367           state_change.state() ==
39368           ObservableEvents::DATA_SOURCE_INSTANCE_STATE_STARTED;
39369     }
39370   }
39371 
39372   if (events.instance_state_changes_size() ||
39373       events.all_data_sources_started()) {
39374     // Data sources are first reported as being stopped before starting, so once
39375     // all the data sources we know about have started we can declare tracing
39376     // begun. In the case where there are no matching data sources for the
39377     // session, the service will report the all_data_sources_started() event
39378     // without adding any instances (only since Android S / Perfetto v10.0).
39379     if (start_complete_callback_ || blocking_start_complete_callback_) {
39380       bool all_data_sources_started = std::all_of(
39381           data_source_states_.cbegin(), data_source_states_.cend(),
39382           [](std::pair<DataSourceHandle, bool> state) { return state.second; });
39383       if (all_data_sources_started)
39384         NotifyStartComplete();
39385     }
39386   }
39387 }
39388 
OnTraceStats(bool success,const TraceStats & trace_stats)39389 void TracingMuxerImpl::ConsumerImpl::OnTraceStats(
39390     bool success,
39391     const TraceStats& trace_stats) {
39392   if (!get_trace_stats_callback_)
39393     return;
39394   TracingSession::GetTraceStatsCallbackArgs callback_arg{};
39395   callback_arg.success = success;
39396   callback_arg.trace_stats_data = trace_stats.SerializeAsArray();
39397   muxer_->task_runner_->PostTask(
39398       std::bind(std::move(get_trace_stats_callback_), std::move(callback_arg)));
39399   get_trace_stats_callback_ = nullptr;
39400 }
39401 
39402 // The callbacks below are not used.
OnDetach(bool)39403 void TracingMuxerImpl::ConsumerImpl::OnDetach(bool) {}
OnAttach(bool,const TraceConfig &)39404 void TracingMuxerImpl::ConsumerImpl::OnAttach(bool, const TraceConfig&) {}
39405 // ----- End of TracingMuxerImpl::ConsumerImpl
39406 
39407 // ----- Begin of TracingMuxerImpl::TracingSessionImpl
39408 
39409 // TracingSessionImpl is the RAII object returned to API clients when they
39410 // invoke Tracing::CreateTracingSession. They use it for starting/stopping
39411 // tracing.
39412 
TracingSessionImpl(TracingMuxerImpl * muxer,TracingSessionGlobalID session_id,BackendType backend_type)39413 TracingMuxerImpl::TracingSessionImpl::TracingSessionImpl(
39414     TracingMuxerImpl* muxer,
39415     TracingSessionGlobalID session_id,
39416     BackendType backend_type)
39417     : muxer_(muxer), session_id_(session_id), backend_type_(backend_type) {}
39418 
39419 // Can be destroyed from any thread.
~TracingSessionImpl()39420 TracingMuxerImpl::TracingSessionImpl::~TracingSessionImpl() {
39421   auto* muxer = muxer_;
39422   auto session_id = session_id_;
39423   muxer->task_runner_->PostTask(
39424       [muxer, session_id] { muxer->DestroyTracingSession(session_id); });
39425 }
39426 
39427 // Can be called from any thread.
Setup(const TraceConfig & cfg,int fd)39428 void TracingMuxerImpl::TracingSessionImpl::Setup(const TraceConfig& cfg,
39429                                                  int fd) {
39430   auto* muxer = muxer_;
39431   auto session_id = session_id_;
39432   std::shared_ptr<TraceConfig> trace_config(new TraceConfig(cfg));
39433   if (fd >= 0) {
39434     base::ignore_result(backend_type_);  // For -Wunused in the amalgamation.
39435 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
39436     if (backend_type_ != kInProcessBackend) {
39437       PERFETTO_FATAL(
39438           "Passing a file descriptor to TracingSession::Setup() is only "
39439           "supported with the kInProcessBackend on Windows. Use "
39440           "TracingSession::ReadTrace() instead");
39441     }
39442 #endif
39443     trace_config->set_write_into_file(true);
39444     fd = dup(fd);
39445   }
39446   muxer->task_runner_->PostTask([muxer, session_id, trace_config, fd] {
39447     muxer->SetupTracingSession(session_id, trace_config, base::ScopedFile(fd));
39448   });
39449 }
39450 
39451 // Can be called from any thread.
Start()39452 void TracingMuxerImpl::TracingSessionImpl::Start() {
39453   auto* muxer = muxer_;
39454   auto session_id = session_id_;
39455   muxer->task_runner_->PostTask(
39456       [muxer, session_id] { muxer->StartTracingSession(session_id); });
39457 }
39458 
39459 // Can be called from any thread.
ChangeTraceConfig(const TraceConfig & cfg)39460 void TracingMuxerImpl::TracingSessionImpl::ChangeTraceConfig(
39461     const TraceConfig& cfg) {
39462   auto* muxer = muxer_;
39463   auto session_id = session_id_;
39464   muxer->task_runner_->PostTask([muxer, session_id, cfg] {
39465     muxer->ChangeTracingSessionConfig(session_id, cfg);
39466   });
39467 }
39468 
39469 // Can be called from any thread except the service thread.
StartBlocking()39470 void TracingMuxerImpl::TracingSessionImpl::StartBlocking() {
39471   PERFETTO_DCHECK(!muxer_->task_runner_->RunsTasksOnCurrentThread());
39472   auto* muxer = muxer_;
39473   auto session_id = session_id_;
39474   base::WaitableEvent tracing_started;
39475   muxer->task_runner_->PostTask([muxer, session_id, &tracing_started] {
39476     auto* consumer = muxer->FindConsumer(session_id);
39477     if (!consumer) {
39478       // TODO(skyostil): Signal an error to the user.
39479       tracing_started.Notify();
39480       return;
39481     }
39482     PERFETTO_DCHECK(!consumer->blocking_start_complete_callback_);
39483     consumer->blocking_start_complete_callback_ = [&] {
39484       tracing_started.Notify();
39485     };
39486     muxer->StartTracingSession(session_id);
39487   });
39488   tracing_started.Wait();
39489 }
39490 
39491 // Can be called from any thread.
Flush(std::function<void (bool)> user_callback,uint32_t timeout_ms)39492 void TracingMuxerImpl::TracingSessionImpl::Flush(
39493     std::function<void(bool)> user_callback,
39494     uint32_t timeout_ms) {
39495   auto* muxer = muxer_;
39496   auto session_id = session_id_;
39497   muxer->task_runner_->PostTask([muxer, session_id, timeout_ms, user_callback] {
39498     auto* consumer = muxer->FindConsumer(session_id);
39499     if (!consumer) {
39500       std::move(user_callback)(false);
39501       return;
39502     }
39503     muxer->FlushTracingSession(session_id, timeout_ms,
39504                                std::move(user_callback));
39505   });
39506 }
39507 
39508 // Can be called from any thread.
Stop()39509 void TracingMuxerImpl::TracingSessionImpl::Stop() {
39510   auto* muxer = muxer_;
39511   auto session_id = session_id_;
39512   muxer->task_runner_->PostTask(
39513       [muxer, session_id] { muxer->StopTracingSession(session_id); });
39514 }
39515 
39516 // Can be called from any thread except the service thread.
StopBlocking()39517 void TracingMuxerImpl::TracingSessionImpl::StopBlocking() {
39518   PERFETTO_DCHECK(!muxer_->task_runner_->RunsTasksOnCurrentThread());
39519   auto* muxer = muxer_;
39520   auto session_id = session_id_;
39521   base::WaitableEvent tracing_stopped;
39522   muxer->task_runner_->PostTask([muxer, session_id, &tracing_stopped] {
39523     auto* consumer = muxer->FindConsumer(session_id);
39524     if (!consumer) {
39525       // TODO(skyostil): Signal an error to the user.
39526       tracing_stopped.Notify();
39527       return;
39528     }
39529     PERFETTO_DCHECK(!consumer->blocking_stop_complete_callback_);
39530     consumer->blocking_stop_complete_callback_ = [&] {
39531       tracing_stopped.Notify();
39532     };
39533     muxer->StopTracingSession(session_id);
39534   });
39535   tracing_stopped.Wait();
39536 }
39537 
39538 // Can be called from any thread.
ReadTrace(ReadTraceCallback cb)39539 void TracingMuxerImpl::TracingSessionImpl::ReadTrace(ReadTraceCallback cb) {
39540   auto* muxer = muxer_;
39541   auto session_id = session_id_;
39542   muxer->task_runner_->PostTask([muxer, session_id, cb] {
39543     muxer->ReadTracingSessionData(session_id, std::move(cb));
39544   });
39545 }
39546 
39547 // Can be called from any thread.
SetOnStartCallback(std::function<void ()> cb)39548 void TracingMuxerImpl::TracingSessionImpl::SetOnStartCallback(
39549     std::function<void()> cb) {
39550   auto* muxer = muxer_;
39551   auto session_id = session_id_;
39552   muxer->task_runner_->PostTask([muxer, session_id, cb] {
39553     auto* consumer = muxer->FindConsumer(session_id);
39554     if (!consumer)
39555       return;
39556     consumer->start_complete_callback_ = cb;
39557   });
39558 }
39559 
39560 // Can be called from any thread
SetOnErrorCallback(std::function<void (TracingError)> cb)39561 void TracingMuxerImpl::TracingSessionImpl::SetOnErrorCallback(
39562     std::function<void(TracingError)> cb) {
39563   auto* muxer = muxer_;
39564   auto session_id = session_id_;
39565   muxer->task_runner_->PostTask([muxer, session_id, cb] {
39566     auto* consumer = muxer->FindConsumer(session_id);
39567     if (!consumer) {
39568       // Notify the client about concurrent disconnection of the session.
39569       if (cb)
39570         cb(TracingError{TracingError::kDisconnected, "Peer disconnected"});
39571       return;
39572     }
39573     consumer->error_callback_ = cb;
39574   });
39575 }
39576 
39577 // Can be called from any thread.
SetOnStopCallback(std::function<void ()> cb)39578 void TracingMuxerImpl::TracingSessionImpl::SetOnStopCallback(
39579     std::function<void()> cb) {
39580   auto* muxer = muxer_;
39581   auto session_id = session_id_;
39582   muxer->task_runner_->PostTask([muxer, session_id, cb] {
39583     auto* consumer = muxer->FindConsumer(session_id);
39584     if (!consumer)
39585       return;
39586     consumer->stop_complete_callback_ = cb;
39587   });
39588 }
39589 
39590 // Can be called from any thread.
GetTraceStats(GetTraceStatsCallback cb)39591 void TracingMuxerImpl::TracingSessionImpl::GetTraceStats(
39592     GetTraceStatsCallback cb) {
39593   auto* muxer = muxer_;
39594   auto session_id = session_id_;
39595   muxer->task_runner_->PostTask([muxer, session_id, cb] {
39596     muxer->GetTraceStats(session_id, std::move(cb));
39597   });
39598 }
39599 
39600 // Can be called from any thread.
QueryServiceState(QueryServiceStateCallback cb)39601 void TracingMuxerImpl::TracingSessionImpl::QueryServiceState(
39602     QueryServiceStateCallback cb) {
39603   auto* muxer = muxer_;
39604   auto session_id = session_id_;
39605   muxer->task_runner_->PostTask([muxer, session_id, cb] {
39606     muxer->QueryServiceState(session_id, std::move(cb));
39607   });
39608 }
39609 
39610 // ----- End of TracingMuxerImpl::TracingSessionImpl
39611 
39612 // static
39613 TracingMuxer* TracingMuxer::instance_ = TracingMuxerFake::Get();
39614 
39615 // This is called by perfetto::Tracing::Initialize().
39616 // Can be called on any thread. Typically, but not necessarily, that will be
39617 // the embedder's main thread.
TracingMuxerImpl(const TracingInitArgs & args)39618 TracingMuxerImpl::TracingMuxerImpl(const TracingInitArgs& args)
39619     : TracingMuxer(args.platform ? args.platform
39620                                  : Platform::GetDefaultPlatform()) {
39621   PERFETTO_DETACH_FROM_THREAD(thread_checker_);
39622   instance_ = this;
39623 
39624   // Create the thread where muxer, producers and service will live.
39625   task_runner_.reset(
39626       new NonReentrantTaskRunner(this, platform_->CreateTaskRunner({})));
39627 
39628   // Run the initializer on that thread.
39629   task_runner_->PostTask([this, args] { Initialize(args); });
39630 }
39631 
Initialize(const TracingInitArgs & args)39632 void TracingMuxerImpl::Initialize(const TracingInitArgs& args) {
39633   PERFETTO_DCHECK_THREAD(thread_checker_);  // Rebind the thread checker.
39634 
39635   policy_ = args.tracing_policy;
39636 
39637   auto add_backend = [this, &args](TracingBackend* backend, BackendType type) {
39638     if (!backend) {
39639       // We skip the log in release builds because the *_backend_fake.cc code
39640       // has already an ELOG before returning a nullptr.
39641       PERFETTO_DLOG("Backend creation failed, type %d", static_cast<int>(type));
39642       return;
39643     }
39644     TracingBackendId backend_id = backends_.size();
39645     backends_.emplace_back();
39646     RegisteredBackend& rb = backends_.back();
39647     rb.backend = backend;
39648     rb.id = backend_id;
39649     rb.type = type;
39650     rb.producer.reset(new ProducerImpl(this, backend_id,
39651                                        args.shmem_batch_commits_duration_ms));
39652     rb.producer_conn_args.producer = rb.producer.get();
39653     rb.producer_conn_args.producer_name = platform_->GetCurrentProcessName();
39654     rb.producer_conn_args.task_runner = task_runner_.get();
39655     rb.producer_conn_args.shmem_size_hint_bytes =
39656         args.shmem_size_hint_kb * 1024;
39657     rb.producer_conn_args.shmem_page_size_hint_bytes =
39658         args.shmem_page_size_hint_kb * 1024;
39659     rb.producer->Initialize(rb.backend->ConnectProducer(rb.producer_conn_args));
39660   };
39661 
39662   if (args.backends & kSystemBackend) {
39663     PERFETTO_CHECK(args.system_backend_factory_);
39664     add_backend(args.system_backend_factory_(), kSystemBackend);
39665   }
39666 
39667   if (args.backends & kInProcessBackend) {
39668     PERFETTO_CHECK(args.in_process_backend_factory_);
39669     add_backend(args.in_process_backend_factory_(), kInProcessBackend);
39670   }
39671 
39672   if (args.backends & kCustomBackend) {
39673     PERFETTO_CHECK(args.custom_backend);
39674     add_backend(args.custom_backend, kCustomBackend);
39675   }
39676 
39677   if (args.backends & ~(kSystemBackend | kInProcessBackend | kCustomBackend)) {
39678     PERFETTO_FATAL("Unsupported tracing backend type");
39679   }
39680 
39681   // Fallback backend for consumer creation for an unsupported backend type.
39682   // This backend simply fails any attempt to start a tracing session.
39683   // NOTE: This backend instance has to be added last.
39684   add_backend(internal::TracingBackendFake::GetInstance(),
39685               BackendType::kUnspecifiedBackend);
39686 }
39687 
39688 // Can be called from any thread (but not concurrently).
RegisterDataSource(const DataSourceDescriptor & descriptor,DataSourceFactory factory,DataSourceStaticState * static_state)39689 bool TracingMuxerImpl::RegisterDataSource(
39690     const DataSourceDescriptor& descriptor,
39691     DataSourceFactory factory,
39692     DataSourceStaticState* static_state) {
39693   // Ignore repeated registrations.
39694   if (static_state->index != kMaxDataSources)
39695     return true;
39696 
39697   static std::atomic<uint32_t> last_id{};
39698   uint32_t new_index = last_id++;
39699   if (new_index >= kMaxDataSources) {
39700     PERFETTO_DLOG(
39701         "RegisterDataSource failed: too many data sources already registered");
39702     return false;
39703   }
39704 
39705   // Initialize the static state.
39706   static_assert(sizeof(static_state->instances[0]) >= sizeof(DataSourceState),
39707                 "instances[] size mismatch");
39708   for (size_t i = 0; i < static_state->instances.size(); i++)
39709     new (&static_state->instances[i]) DataSourceState{};
39710 
39711   static_state->index = new_index;
39712 
39713   task_runner_->PostTask([this, descriptor, factory, static_state] {
39714     data_sources_.emplace_back();
39715     RegisteredDataSource& rds = data_sources_.back();
39716     rds.descriptor = descriptor;
39717     rds.factory = factory;
39718     rds.static_state = static_state;
39719     UpdateDataSourcesOnAllBackends();
39720   });
39721   return true;
39722 }
39723 
39724 // Can be called from any thread (but not concurrently).
RegisterInterceptor(const InterceptorDescriptor & descriptor,InterceptorFactory factory,InterceptorBase::TLSFactory tls_factory,InterceptorBase::TracePacketCallback packet_callback)39725 void TracingMuxerImpl::RegisterInterceptor(
39726     const InterceptorDescriptor& descriptor,
39727     InterceptorFactory factory,
39728     InterceptorBase::TLSFactory tls_factory,
39729     InterceptorBase::TracePacketCallback packet_callback) {
39730   task_runner_->PostTask(
39731       [this, descriptor, factory, tls_factory, packet_callback] {
39732         // Ignore repeated registrations.
39733         for (const auto& interceptor : interceptors_) {
39734           if (interceptor.descriptor.name() == descriptor.name()) {
39735             PERFETTO_DCHECK(interceptor.tls_factory == tls_factory);
39736             PERFETTO_DCHECK(interceptor.packet_callback == packet_callback);
39737             return;
39738           }
39739         }
39740         // Only allow certain interceptors for now.
39741         if (descriptor.name() != "test_interceptor" &&
39742             descriptor.name() != "console") {
39743           PERFETTO_ELOG(
39744               "Interceptors are experimental. If you want to use them, please "
39745               "get in touch with the project maintainers "
39746               "(https://perfetto.dev/docs/contributing/"
39747               "getting-started#community).");
39748           return;
39749         }
39750         interceptors_.emplace_back();
39751         RegisteredInterceptor& interceptor = interceptors_.back();
39752         interceptor.descriptor = descriptor;
39753         interceptor.factory = factory;
39754         interceptor.tls_factory = tls_factory;
39755         interceptor.packet_callback = packet_callback;
39756       });
39757 }
39758 
39759 // Called by the service of one of the backends.
SetupDataSource(TracingBackendId backend_id,uint32_t backend_connection_id,DataSourceInstanceID instance_id,const DataSourceConfig & cfg)39760 void TracingMuxerImpl::SetupDataSource(TracingBackendId backend_id,
39761                                        uint32_t backend_connection_id,
39762                                        DataSourceInstanceID instance_id,
39763                                        const DataSourceConfig& cfg) {
39764   PERFETTO_DCHECK_THREAD(thread_checker_);
39765   PERFETTO_DLOG("Setting up data source %" PRIu64 " %s", instance_id,
39766                 cfg.name().c_str());
39767   uint64_t config_hash = ComputeConfigHash(cfg);
39768 
39769   for (const auto& rds : data_sources_) {
39770     if (rds.descriptor.name() != cfg.name())
39771       continue;
39772     DataSourceStaticState& static_state = *rds.static_state;
39773 
39774     // If this data source is already active for this exact config, don't start
39775     // another instance. This happens when we have several data sources with the
39776     // same name, in which case the service sends one SetupDataSource event for
39777     // each one. Since we can't map which event maps to which data source, we
39778     // ensure each event only starts one data source instance.
39779     // TODO(skyostil): Register a unique id with each data source to the service
39780     // to disambiguate.
39781     bool active_for_config = false;
39782     for (uint32_t i = 0; i < kMaxDataSourceInstances; i++) {
39783       if (!static_state.TryGet(i))
39784         continue;
39785       auto* internal_state =
39786           reinterpret_cast<DataSourceState*>(&static_state.instances[i]);
39787       if (internal_state->backend_id == backend_id &&
39788           internal_state->config_hash == config_hash) {
39789         active_for_config = true;
39790         break;
39791       }
39792     }
39793     if (active_for_config) {
39794       PERFETTO_DLOG(
39795           "Data source %s is already active with this config, skipping",
39796           cfg.name().c_str());
39797       continue;
39798     }
39799 
39800     for (uint32_t i = 0; i < kMaxDataSourceInstances; i++) {
39801       // Find a free slot.
39802       if (static_state.TryGet(i))
39803         continue;
39804 
39805       auto* internal_state =
39806           reinterpret_cast<DataSourceState*>(&static_state.instances[i]);
39807       std::lock_guard<std::recursive_mutex> guard(internal_state->lock);
39808       static_assert(
39809           std::is_same<decltype(internal_state->data_source_instance_id),
39810                        DataSourceInstanceID>::value,
39811           "data_source_instance_id type mismatch");
39812       internal_state->backend_id = backend_id;
39813       internal_state->backend_connection_id = backend_connection_id;
39814       internal_state->data_source_instance_id = instance_id;
39815       internal_state->buffer_id =
39816           static_cast<internal::BufferId>(cfg.target_buffer());
39817       internal_state->config_hash = config_hash;
39818       internal_state->data_source = rds.factory();
39819       internal_state->interceptor = nullptr;
39820       internal_state->interceptor_id = 0;
39821 
39822       if (cfg.has_interceptor_config()) {
39823         for (size_t j = 0; j < interceptors_.size(); j++) {
39824           if (cfg.interceptor_config().name() ==
39825               interceptors_[j].descriptor.name()) {
39826             PERFETTO_DLOG("Intercepting data source %" PRIu64
39827                           " \"%s\" into \"%s\"",
39828                           instance_id, cfg.name().c_str(),
39829                           cfg.interceptor_config().name().c_str());
39830             internal_state->interceptor_id = static_cast<uint32_t>(j + 1);
39831             internal_state->interceptor = interceptors_[j].factory();
39832             internal_state->interceptor->OnSetup({cfg});
39833             break;
39834           }
39835         }
39836         if (!internal_state->interceptor_id) {
39837           PERFETTO_ELOG("Unknown interceptor configured for data source: %s",
39838                         cfg.interceptor_config().name().c_str());
39839         }
39840       }
39841 
39842       // This must be made at the end. See matching acquire-load in
39843       // DataSource::Trace().
39844       static_state.valid_instances.fetch_or(1 << i, std::memory_order_release);
39845 
39846       DataSourceBase::SetupArgs setup_args;
39847       setup_args.config = &cfg;
39848       setup_args.internal_instance_index = i;
39849       internal_state->data_source->OnSetup(setup_args);
39850       return;
39851     }
39852     PERFETTO_ELOG(
39853         "Maximum number of data source instances exhausted. "
39854         "Dropping data source %" PRIu64,
39855         instance_id);
39856     break;
39857   }
39858 }
39859 
39860 // Called by the service of one of the backends.
StartDataSource(TracingBackendId backend_id,DataSourceInstanceID instance_id)39861 void TracingMuxerImpl::StartDataSource(TracingBackendId backend_id,
39862                                        DataSourceInstanceID instance_id) {
39863   PERFETTO_DLOG("Starting data source %" PRIu64, instance_id);
39864   PERFETTO_DCHECK_THREAD(thread_checker_);
39865 
39866   auto ds = FindDataSource(backend_id, instance_id);
39867   if (!ds) {
39868     PERFETTO_ELOG("Could not find data source to start");
39869     return;
39870   }
39871 
39872   DataSourceBase::StartArgs start_args{};
39873   start_args.internal_instance_index = ds.instance_idx;
39874 
39875   std::lock_guard<std::recursive_mutex> guard(ds.internal_state->lock);
39876   if (ds.internal_state->interceptor)
39877     ds.internal_state->interceptor->OnStart({});
39878   ds.internal_state->trace_lambda_enabled = true;
39879   ds.internal_state->data_source->OnStart(start_args);
39880 }
39881 
39882 // Called by the service of one of the backends.
StopDataSource_AsyncBegin(TracingBackendId backend_id,DataSourceInstanceID instance_id)39883 void TracingMuxerImpl::StopDataSource_AsyncBegin(
39884     TracingBackendId backend_id,
39885     DataSourceInstanceID instance_id) {
39886   PERFETTO_DLOG("Stopping data source %" PRIu64, instance_id);
39887   PERFETTO_DCHECK_THREAD(thread_checker_);
39888 
39889   auto ds = FindDataSource(backend_id, instance_id);
39890   if (!ds) {
39891     PERFETTO_ELOG("Could not find data source to stop");
39892     return;
39893   }
39894 
39895   StopArgsImpl stop_args{};
39896   stop_args.internal_instance_index = ds.instance_idx;
39897   stop_args.async_stop_closure = [this, backend_id, instance_id] {
39898     // TracingMuxerImpl is long lived, capturing |this| is okay.
39899     // The notification closure can be moved out of the StopArgs by the
39900     // embedder to handle stop asynchronously. The embedder might then
39901     // call the closure on a different thread than the current one, hence
39902     // this nested PostTask().
39903     task_runner_->PostTask([this, backend_id, instance_id] {
39904       StopDataSource_AsyncEnd(backend_id, instance_id);
39905     });
39906   };
39907 
39908   {
39909     std::lock_guard<std::recursive_mutex> guard(ds.internal_state->lock);
39910     if (ds.internal_state->interceptor)
39911       ds.internal_state->interceptor->OnStop({});
39912     ds.internal_state->data_source->OnStop(stop_args);
39913   }
39914 
39915   // If the embedder hasn't called StopArgs.HandleStopAsynchronously() run the
39916   // async closure here. In theory we could avoid the PostTask and call
39917   // straight into CompleteDataSourceAsyncStop(). We keep that to reduce
39918   // divergencies between the deferred-stop vs non-deferred-stop code paths.
39919   if (stop_args.async_stop_closure)
39920     std::move(stop_args.async_stop_closure)();
39921 }
39922 
StopDataSource_AsyncEnd(TracingBackendId backend_id,DataSourceInstanceID instance_id)39923 void TracingMuxerImpl::StopDataSource_AsyncEnd(
39924     TracingBackendId backend_id,
39925     DataSourceInstanceID instance_id) {
39926   PERFETTO_DLOG("Ending async stop of data source %" PRIu64, instance_id);
39927   PERFETTO_DCHECK_THREAD(thread_checker_);
39928 
39929   auto ds = FindDataSource(backend_id, instance_id);
39930   if (!ds) {
39931     PERFETTO_ELOG(
39932         "Async stop of data source %" PRIu64
39933         " failed. This might be due to calling the async_stop_closure twice.",
39934         instance_id);
39935     return;
39936   }
39937 
39938   const uint32_t mask = ~(1 << ds.instance_idx);
39939   ds.static_state->valid_instances.fetch_and(mask, std::memory_order_acq_rel);
39940 
39941   // Take the mutex to prevent that the data source is in the middle of
39942   // a Trace() execution where it called GetDataSourceLocked() while we
39943   // destroy it.
39944   {
39945     std::lock_guard<std::recursive_mutex> guard(ds.internal_state->lock);
39946     ds.internal_state->trace_lambda_enabled = false;
39947     ds.internal_state->data_source.reset();
39948   }
39949 
39950   // The other fields of internal_state are deliberately *not* cleared.
39951   // See races-related comments of DataSource::Trace().
39952 
39953   TracingMuxer::generation_++;
39954 
39955   // |backends_| is append-only, Backend instances are always valid.
39956   PERFETTO_CHECK(backend_id < backends_.size());
39957   ProducerImpl* producer = backends_[backend_id].producer.get();
39958   if (!producer)
39959     return;
39960   if (producer->connected_) {
39961     // Flush any commits that might have been batched by SharedMemoryArbiter.
39962     producer->service_->MaybeSharedMemoryArbiter()
39963         ->FlushPendingCommitDataRequests();
39964     producer->service_->NotifyDataSourceStopped(instance_id);
39965   }
39966   producer->SweepDeadServices();
39967 }
39968 
ClearDataSourceIncrementalState(TracingBackendId backend_id,DataSourceInstanceID instance_id)39969 void TracingMuxerImpl::ClearDataSourceIncrementalState(
39970     TracingBackendId backend_id,
39971     DataSourceInstanceID instance_id) {
39972   PERFETTO_DCHECK_THREAD(thread_checker_);
39973   PERFETTO_DLOG("Clearing incremental state for data source %" PRIu64,
39974                 instance_id);
39975   auto ds = FindDataSource(backend_id, instance_id);
39976   if (!ds) {
39977     PERFETTO_ELOG("Could not find data source to clear incremental state for");
39978     return;
39979   }
39980   // Make DataSource::TraceContext::GetIncrementalState() eventually notice that
39981   // the incremental state should be cleared.
39982   ds.static_state->incremental_state_generation.fetch_add(
39983       1, std::memory_order_relaxed);
39984 }
39985 
SyncProducersForTesting()39986 void TracingMuxerImpl::SyncProducersForTesting() {
39987   std::mutex mutex;
39988   std::condition_variable cv;
39989 
39990   // IPC-based producers don't report connection errors explicitly for each
39991   // command, but instead with an asynchronous callback
39992   // (ProducerImpl::OnDisconnected). This means that the sync command below
39993   // may have completed but failed to reach the service because of a
39994   // disconnection, but we can't tell until the disconnection message comes
39995   // through. To guard against this, we run two whole rounds of sync round-trips
39996   // before returning; the first one will detect any disconnected producers and
39997   // the second one will ensure any reconnections have completed and all data
39998   // sources are registered in the service again.
39999   for (size_t i = 0; i < 2; i++) {
40000     size_t countdown = std::numeric_limits<size_t>::max();
40001     task_runner_->PostTask([this, &mutex, &cv, &countdown] {
40002       {
40003         std::unique_lock<std::mutex> countdown_lock(mutex);
40004         countdown = backends_.size();
40005       }
40006       for (auto& backend : backends_) {
40007         auto* producer = backend.producer.get();
40008         producer->service_->Sync([&mutex, &cv, &countdown] {
40009           std::unique_lock<std::mutex> countdown_lock(mutex);
40010           countdown--;
40011           cv.notify_one();
40012         });
40013       }
40014     });
40015 
40016     {
40017       std::unique_lock<std::mutex> countdown_lock(mutex);
40018       cv.wait(countdown_lock, [&countdown] { return !countdown; });
40019     }
40020   }
40021 
40022   // Check that all producers are indeed connected.
40023   bool done = false;
40024   bool all_producers_connected = true;
40025   task_runner_->PostTask([this, &mutex, &cv, &done, &all_producers_connected] {
40026     for (auto& backend : backends_)
40027       all_producers_connected &= backend.producer->connected_;
40028     std::unique_lock<std::mutex> lock(mutex);
40029     done = true;
40030     cv.notify_one();
40031   });
40032 
40033   {
40034     std::unique_lock<std::mutex> lock(mutex);
40035     cv.wait(lock, [&done] { return done; });
40036   }
40037   PERFETTO_DCHECK(all_producers_connected);
40038 }
40039 
DestroyStoppedTraceWritersForCurrentThread()40040 void TracingMuxerImpl::DestroyStoppedTraceWritersForCurrentThread() {
40041   // Iterate across all possible data source types.
40042   auto cur_generation = generation_.load(std::memory_order_acquire);
40043   auto* root_tls = GetOrCreateTracingTLS();
40044 
40045   auto destroy_stopped_instances = [](DataSourceThreadLocalState& tls) {
40046     // |tls| has a vector of per-data-source-instance thread-local state.
40047     DataSourceStaticState* static_state = tls.static_state;
40048     if (!static_state)
40049       return;  // Slot not used.
40050 
40051     // Iterate across all possible instances for this data source.
40052     for (uint32_t inst = 0; inst < kMaxDataSourceInstances; inst++) {
40053       DataSourceInstanceThreadLocalState& ds_tls = tls.per_instance[inst];
40054       if (!ds_tls.trace_writer)
40055         continue;
40056 
40057       DataSourceState* ds_state = static_state->TryGet(inst);
40058       if (ds_state && ds_state->backend_id == ds_tls.backend_id &&
40059           ds_state->backend_connection_id == ds_tls.backend_connection_id &&
40060           ds_state->buffer_id == ds_tls.buffer_id &&
40061           ds_state->data_source_instance_id == ds_tls.data_source_instance_id) {
40062         continue;
40063       }
40064 
40065       // The DataSource instance has been destroyed or recycled.
40066       ds_tls.Reset();  // Will also destroy the |ds_tls.trace_writer|.
40067     }
40068   };
40069 
40070   for (size_t ds_idx = 0; ds_idx < kMaxDataSources; ds_idx++) {
40071     // |tls| has a vector of per-data-source-instance thread-local state.
40072     DataSourceThreadLocalState& tls = root_tls->data_sources_tls[ds_idx];
40073     destroy_stopped_instances(tls);
40074   }
40075   destroy_stopped_instances(root_tls->track_event_tls);
40076   root_tls->generation = cur_generation;
40077 }
40078 
40079 // Called both when a new data source is registered or when a new backend
40080 // connects. In both cases we want to be sure we reflected the data source
40081 // registrations on the backends.
UpdateDataSourcesOnAllBackends()40082 void TracingMuxerImpl::UpdateDataSourcesOnAllBackends() {
40083   PERFETTO_DCHECK_THREAD(thread_checker_);
40084   for (RegisteredDataSource& rds : data_sources_) {
40085     for (RegisteredBackend& backend : backends_) {
40086       // We cannot call RegisterDataSource on the backend before it connects.
40087       if (!backend.producer->connected_)
40088         continue;
40089 
40090       PERFETTO_DCHECK(rds.static_state->index < kMaxDataSources);
40091       if (backend.producer->registered_data_sources_.test(
40092               rds.static_state->index))
40093         continue;
40094 
40095       rds.descriptor.set_will_notify_on_start(true);
40096       rds.descriptor.set_will_notify_on_stop(true);
40097       rds.descriptor.set_handles_incremental_state_clear(true);
40098       backend.producer->service_->RegisterDataSource(rds.descriptor);
40099       backend.producer->registered_data_sources_.set(rds.static_state->index);
40100     }
40101   }
40102 }
40103 
SetupTracingSession(TracingSessionGlobalID session_id,const std::shared_ptr<TraceConfig> & trace_config,base::ScopedFile trace_fd)40104 void TracingMuxerImpl::SetupTracingSession(
40105     TracingSessionGlobalID session_id,
40106     const std::shared_ptr<TraceConfig>& trace_config,
40107     base::ScopedFile trace_fd) {
40108   PERFETTO_DCHECK_THREAD(thread_checker_);
40109   PERFETTO_CHECK(!trace_fd || trace_config->write_into_file());
40110 
40111   auto* consumer = FindConsumer(session_id);
40112   if (!consumer)
40113     return;
40114 
40115   consumer->trace_config_ = trace_config;
40116   if (trace_fd)
40117     consumer->trace_fd_ = std::move(trace_fd);
40118 
40119   if (!consumer->connected_)
40120     return;
40121 
40122   // Only used in the deferred start mode.
40123   if (trace_config->deferred_start()) {
40124     consumer->service_->EnableTracing(*trace_config,
40125                                       std::move(consumer->trace_fd_));
40126   }
40127 }
40128 
StartTracingSession(TracingSessionGlobalID session_id)40129 void TracingMuxerImpl::StartTracingSession(TracingSessionGlobalID session_id) {
40130   PERFETTO_DCHECK_THREAD(thread_checker_);
40131 
40132   auto* consumer = FindConsumer(session_id);
40133 
40134   if (!consumer)
40135     return;
40136 
40137   if (!consumer->trace_config_) {
40138     PERFETTO_ELOG("Must call Setup(config) first");
40139     return;
40140   }
40141 
40142   if (!consumer->connected_) {
40143     consumer->start_pending_ = true;
40144     return;
40145   }
40146 
40147   consumer->start_pending_ = false;
40148   if (consumer->trace_config_->deferred_start()) {
40149     consumer->service_->StartTracing();
40150   } else {
40151     consumer->service_->EnableTracing(*consumer->trace_config_,
40152                                       std::move(consumer->trace_fd_));
40153   }
40154 
40155   // TODO implement support for the deferred-start + fast-triggering case.
40156 }
40157 
ChangeTracingSessionConfig(TracingSessionGlobalID session_id,const TraceConfig & trace_config)40158 void TracingMuxerImpl::ChangeTracingSessionConfig(
40159     TracingSessionGlobalID session_id,
40160     const TraceConfig& trace_config) {
40161   PERFETTO_DCHECK_THREAD(thread_checker_);
40162 
40163   auto* consumer = FindConsumer(session_id);
40164 
40165   if (!consumer)
40166     return;
40167 
40168   if (!consumer->trace_config_) {
40169     // Changing the config is only supported for started sessions.
40170     PERFETTO_ELOG("Must call Setup(config) and Start() first");
40171     return;
40172   }
40173 
40174   consumer->trace_config_ = std::make_shared<TraceConfig>(trace_config);
40175   if (consumer->connected_)
40176     consumer->service_->ChangeTraceConfig(trace_config);
40177 }
40178 
FlushTracingSession(TracingSessionGlobalID session_id,uint32_t timeout_ms,std::function<void (bool)> callback)40179 void TracingMuxerImpl::FlushTracingSession(TracingSessionGlobalID session_id,
40180                                            uint32_t timeout_ms,
40181                                            std::function<void(bool)> callback) {
40182   PERFETTO_DCHECK_THREAD(thread_checker_);
40183   auto* consumer = FindConsumer(session_id);
40184   if (!consumer || consumer->start_pending_ || consumer->stop_pending_ ||
40185       !consumer->trace_config_) {
40186     PERFETTO_ELOG("Flush() can be called only after Start() and before Stop()");
40187     std::move(callback)(false);
40188     return;
40189   }
40190 
40191   consumer->service_->Flush(timeout_ms, std::move(callback));
40192 }
40193 
StopTracingSession(TracingSessionGlobalID session_id)40194 void TracingMuxerImpl::StopTracingSession(TracingSessionGlobalID session_id) {
40195   PERFETTO_DCHECK_THREAD(thread_checker_);
40196   auto* consumer = FindConsumer(session_id);
40197   if (!consumer)
40198     return;
40199 
40200   if (consumer->start_pending_) {
40201     // If the session hasn't started yet, wait until it does before stopping.
40202     consumer->stop_pending_ = true;
40203     return;
40204   }
40205 
40206   consumer->stop_pending_ = false;
40207   if (consumer->stopped_) {
40208     // If the session was already stopped (e.g., it failed to start), don't try
40209     // stopping again.
40210     consumer->NotifyStopComplete();
40211   } else if (!consumer->trace_config_) {
40212     PERFETTO_ELOG("Must call Setup(config) and Start() first");
40213     return;
40214   } else {
40215     consumer->service_->DisableTracing();
40216   }
40217 
40218   consumer->trace_config_.reset();
40219 }
40220 
DestroyTracingSession(TracingSessionGlobalID session_id)40221 void TracingMuxerImpl::DestroyTracingSession(
40222     TracingSessionGlobalID session_id) {
40223   PERFETTO_DCHECK_THREAD(thread_checker_);
40224   for (RegisteredBackend& backend : backends_) {
40225     // We need to find the consumer (if any) and call Disconnect as we destroy
40226     // the tracing session. We can't call Disconnect() inside this for loop
40227     // because in the in-process case this will end up to a synchronous call to
40228     // OnConsumerDisconnect which will invalidate all the iterators to
40229     // |backend.consumers|.
40230     ConsumerImpl* consumer = nullptr;
40231     for (auto& con : backend.consumers) {
40232       if (con->session_id_ == session_id) {
40233         consumer = con.get();
40234         break;
40235       }
40236     }
40237     if (consumer) {
40238       // We broke out of the loop above on the assumption that each backend will
40239       // only have a single consumer per session. This DCHECK ensures that
40240       // this is the case.
40241       PERFETTO_DCHECK(
40242           std::count_if(backend.consumers.begin(), backend.consumers.end(),
40243                         [session_id](const std::unique_ptr<ConsumerImpl>& con) {
40244                           return con->session_id_ == session_id;
40245                         }) == 1u);
40246       consumer->Disconnect();
40247     }
40248   }
40249 }
40250 
ReadTracingSessionData(TracingSessionGlobalID session_id,std::function<void (TracingSession::ReadTraceCallbackArgs)> callback)40251 void TracingMuxerImpl::ReadTracingSessionData(
40252     TracingSessionGlobalID session_id,
40253     std::function<void(TracingSession::ReadTraceCallbackArgs)> callback) {
40254   PERFETTO_DCHECK_THREAD(thread_checker_);
40255   auto* consumer = FindConsumer(session_id);
40256   if (!consumer) {
40257     // TODO(skyostil): Signal an error to the user.
40258     TracingSession::ReadTraceCallbackArgs callback_arg{};
40259     callback(callback_arg);
40260     return;
40261   }
40262   PERFETTO_DCHECK(!consumer->read_trace_callback_);
40263   consumer->read_trace_callback_ = std::move(callback);
40264   consumer->service_->ReadBuffers();
40265 }
40266 
GetTraceStats(TracingSessionGlobalID session_id,TracingSession::GetTraceStatsCallback callback)40267 void TracingMuxerImpl::GetTraceStats(
40268     TracingSessionGlobalID session_id,
40269     TracingSession::GetTraceStatsCallback callback) {
40270   PERFETTO_DCHECK_THREAD(thread_checker_);
40271   auto* consumer = FindConsumer(session_id);
40272   if (!consumer) {
40273     TracingSession::GetTraceStatsCallbackArgs callback_arg{};
40274     callback_arg.success = false;
40275     callback(std::move(callback_arg));
40276     return;
40277   }
40278   PERFETTO_DCHECK(!consumer->get_trace_stats_callback_);
40279   consumer->get_trace_stats_callback_ = std::move(callback);
40280   if (!consumer->connected_) {
40281     consumer->get_trace_stats_pending_ = true;
40282     return;
40283   }
40284   consumer->get_trace_stats_pending_ = false;
40285   consumer->service_->GetTraceStats();
40286 }
40287 
QueryServiceState(TracingSessionGlobalID session_id,TracingSession::QueryServiceStateCallback callback)40288 void TracingMuxerImpl::QueryServiceState(
40289     TracingSessionGlobalID session_id,
40290     TracingSession::QueryServiceStateCallback callback) {
40291   PERFETTO_DCHECK_THREAD(thread_checker_);
40292   auto* consumer = FindConsumer(session_id);
40293   if (!consumer) {
40294     TracingSession::QueryServiceStateCallbackArgs callback_arg{};
40295     callback_arg.success = false;
40296     callback(std::move(callback_arg));
40297     return;
40298   }
40299   PERFETTO_DCHECK(!consumer->query_service_state_callback_);
40300   if (!consumer->connected_) {
40301     consumer->query_service_state_callback_ = std::move(callback);
40302     return;
40303   }
40304   auto callback_wrapper = [callback](bool success,
40305                                      protos::gen::TracingServiceState state) {
40306     TracingSession::QueryServiceStateCallbackArgs callback_arg{};
40307     callback_arg.success = success;
40308     callback_arg.service_state_data = state.SerializeAsArray();
40309     callback(std::move(callback_arg));
40310   };
40311   consumer->service_->QueryServiceState(std::move(callback_wrapper));
40312 }
40313 
SetBatchCommitsDurationForTesting(uint32_t batch_commits_duration_ms,BackendType backend_type)40314 void TracingMuxerImpl::SetBatchCommitsDurationForTesting(
40315     uint32_t batch_commits_duration_ms,
40316     BackendType backend_type) {
40317   for (RegisteredBackend& backend : backends_) {
40318     if (backend.producer && backend.producer->connected_ &&
40319         backend.type == backend_type) {
40320       backend.producer->service_->MaybeSharedMemoryArbiter()
40321           ->SetBatchCommitsDuration(batch_commits_duration_ms);
40322     }
40323   }
40324 }
40325 
EnableDirectSMBPatchingForTesting(BackendType backend_type)40326 bool TracingMuxerImpl::EnableDirectSMBPatchingForTesting(
40327     BackendType backend_type) {
40328   for (RegisteredBackend& backend : backends_) {
40329     if (backend.producer && backend.producer->connected_ &&
40330         backend.type == backend_type &&
40331         !backend.producer->service_->MaybeSharedMemoryArbiter()
40332              ->EnableDirectSMBPatching()) {
40333       return false;
40334     }
40335   }
40336   return true;
40337 }
40338 
FindConsumer(TracingSessionGlobalID session_id)40339 TracingMuxerImpl::ConsumerImpl* TracingMuxerImpl::FindConsumer(
40340     TracingSessionGlobalID session_id) {
40341   PERFETTO_DCHECK_THREAD(thread_checker_);
40342   for (RegisteredBackend& backend : backends_) {
40343     for (auto& consumer : backend.consumers) {
40344       if (consumer->session_id_ == session_id) {
40345         return consumer.get();
40346       }
40347     }
40348   }
40349   return nullptr;
40350 }
40351 
InitializeConsumer(TracingSessionGlobalID session_id)40352 void TracingMuxerImpl::InitializeConsumer(TracingSessionGlobalID session_id) {
40353   PERFETTO_DCHECK_THREAD(thread_checker_);
40354 
40355   auto* consumer = FindConsumer(session_id);
40356   if (!consumer)
40357     return;
40358 
40359   TracingBackendId backend_id = consumer->backend_id_;
40360   // |backends_| is append-only, Backend instances are always valid.
40361   PERFETTO_CHECK(backend_id < backends_.size());
40362   RegisteredBackend& backend = backends_[backend_id];
40363 
40364   TracingBackend::ConnectConsumerArgs conn_args;
40365   conn_args.consumer = consumer;
40366   conn_args.task_runner = task_runner_.get();
40367   consumer->Initialize(backend.backend->ConnectConsumer(conn_args));
40368 }
40369 
OnConsumerDisconnected(ConsumerImpl * consumer)40370 void TracingMuxerImpl::OnConsumerDisconnected(ConsumerImpl* consumer) {
40371   PERFETTO_DCHECK_THREAD(thread_checker_);
40372   for (RegisteredBackend& backend : backends_) {
40373     auto pred = [consumer](const std::unique_ptr<ConsumerImpl>& con) {
40374       return con.get() == consumer;
40375     };
40376     backend.consumers.erase(std::remove_if(backend.consumers.begin(),
40377                                            backend.consumers.end(), pred),
40378                             backend.consumers.end());
40379   }
40380 }
40381 
SetMaxProducerReconnectionsForTesting(uint32_t count)40382 void TracingMuxerImpl::SetMaxProducerReconnectionsForTesting(uint32_t count) {
40383   max_producer_reconnections_.store(count);
40384 }
40385 
OnProducerDisconnected(ProducerImpl * producer)40386 void TracingMuxerImpl::OnProducerDisconnected(ProducerImpl* producer) {
40387   PERFETTO_DCHECK_THREAD(thread_checker_);
40388   for (RegisteredBackend& backend : backends_) {
40389     if (backend.producer.get() != producer)
40390       continue;
40391     // Try reconnecting the disconnected producer. If the connection succeeds,
40392     // all the data sources will be automatically re-registered.
40393     if (producer->connection_id_ > max_producer_reconnections_.load()) {
40394       // Avoid reconnecting a failing producer too many times. Instead we just
40395       // leak the producer instead of trying to avoid further complicating
40396       // cross-thread trace writer creation.
40397       PERFETTO_ELOG("Producer disconnected too many times; not reconnecting");
40398       continue;
40399     }
40400     backend.producer->Initialize(
40401         backend.backend->ConnectProducer(backend.producer_conn_args));
40402   }
40403 
40404   // Increment the generation counter to atomically ensure that:
40405   // 1. Old trace writers from the severed connection eventually get cleaned up
40406   //    by DestroyStoppedTraceWritersForCurrentThread().
40407   // 2. No new trace writers can be created for the SharedMemoryArbiter from the
40408   //    old connection.
40409   TracingMuxer::generation_++;
40410 }
40411 
FindDataSource(TracingBackendId backend_id,DataSourceInstanceID instance_id)40412 TracingMuxerImpl::FindDataSourceRes TracingMuxerImpl::FindDataSource(
40413     TracingBackendId backend_id,
40414     DataSourceInstanceID instance_id) {
40415   PERFETTO_DCHECK_THREAD(thread_checker_);
40416   for (const auto& rds : data_sources_) {
40417     DataSourceStaticState* static_state = rds.static_state;
40418     for (uint32_t i = 0; i < kMaxDataSourceInstances; i++) {
40419       auto* internal_state = static_state->TryGet(i);
40420       if (internal_state && internal_state->backend_id == backend_id &&
40421           internal_state->data_source_instance_id == instance_id) {
40422         return FindDataSourceRes(static_state, internal_state, i);
40423       }
40424     }
40425   }
40426   return FindDataSourceRes();
40427 }
40428 
40429 // Can be called from any thread.
CreateTraceWriter(DataSourceStaticState * static_state,uint32_t data_source_instance_index,DataSourceState * data_source,BufferExhaustedPolicy buffer_exhausted_policy)40430 std::unique_ptr<TraceWriterBase> TracingMuxerImpl::CreateTraceWriter(
40431     DataSourceStaticState* static_state,
40432     uint32_t data_source_instance_index,
40433     DataSourceState* data_source,
40434     BufferExhaustedPolicy buffer_exhausted_policy) {
40435   if (PERFETTO_UNLIKELY(data_source->interceptor_id)) {
40436     // If the session is being intercepted, return a heap-backed trace writer
40437     // instead. This is safe because all the data given to the interceptor is
40438     // either thread-local (|instance_index|), statically allocated
40439     // (|static_state|) or constant after initialization (|interceptor|). Access
40440     // to the interceptor instance itself through |data_source| is protected by
40441     // a statically allocated lock (similarly to the data source instance).
40442     auto& interceptor = interceptors_[data_source->interceptor_id - 1];
40443     return std::unique_ptr<TraceWriterBase>(new InterceptorTraceWriter(
40444         interceptor.tls_factory(static_state, data_source_instance_index),
40445         interceptor.packet_callback, static_state, data_source_instance_index));
40446   }
40447   ProducerImpl* producer = backends_[data_source->backend_id].producer.get();
40448   // Atomically load the current service endpoint. We keep the pointer as a
40449   // shared pointer on the stack to guard against it from being concurrently
40450   // modified on the thread by ProducerImpl::Initialize() swapping in a
40451   // reconnected service on the muxer task runner thread.
40452   //
40453   // The endpoint may also be concurrently modified by SweepDeadServices()
40454   // clearing out old disconnected services. We guard against that by
40455   // SharedMemoryArbiter keeping track of any outstanding trace writers. After
40456   // shutdown has started, the trace writer created below will be a null one
40457   // which will drop any written data. See SharedMemoryArbiter::TryShutdown().
40458   //
40459   // We use an atomic pointer instead of holding a lock because
40460   // CreateTraceWriter posts tasks under the hood.
40461   std::shared_ptr<ProducerEndpoint> service =
40462       std::atomic_load(&producer->service_);
40463   return service->CreateTraceWriter(data_source->buffer_id,
40464                                     buffer_exhausted_policy);
40465 }
40466 
40467 // This is called via the public API Tracing::NewTrace().
40468 // Can be called from any thread.
CreateTracingSession(BackendType requested_backend_type)40469 std::unique_ptr<TracingSession> TracingMuxerImpl::CreateTracingSession(
40470     BackendType requested_backend_type) {
40471   TracingSessionGlobalID session_id = ++next_tracing_session_id_;
40472 
40473   // |backend_type| can only specify one backend, not an OR-ed mask.
40474   PERFETTO_CHECK((requested_backend_type & (requested_backend_type - 1)) == 0);
40475 
40476   // Capturing |this| is fine because the TracingMuxer is a leaky singleton.
40477   task_runner_->PostTask([this, requested_backend_type, session_id] {
40478     for (RegisteredBackend& backend : backends_) {
40479       if (requested_backend_type && backend.type &&
40480           backend.type != requested_backend_type) {
40481         continue;
40482       }
40483 
40484       TracingBackendId backend_id = backend.id;
40485 
40486       // Create the consumer now, even if we have to ask the embedder below, so
40487       // that any other tasks executing after this one can find the consumer and
40488       // change its pending attributes.
40489       backend.consumers.emplace_back(
40490           new ConsumerImpl(this, backend.type, backend.id, session_id));
40491 
40492       // The last registered backend in |backends_| is the unsupported backend
40493       // without a valid type.
40494       if (!backend.type) {
40495         PERFETTO_ELOG(
40496             "No tracing backend ready for type=%d, consumer will disconnect",
40497             requested_backend_type);
40498         InitializeConsumer(session_id);
40499         return;
40500       }
40501 
40502       // Check if the embedder wants to be asked for permission before
40503       // connecting the consumer.
40504       if (!policy_) {
40505         InitializeConsumer(session_id);
40506         return;
40507       }
40508 
40509       TracingPolicy::ShouldAllowConsumerSessionArgs args;
40510       args.backend_type = backend.type;
40511       args.result_callback = [this, backend_id, session_id](bool allow) {
40512         task_runner_->PostTask([this, backend_id, session_id, allow] {
40513           if (allow) {
40514             InitializeConsumer(session_id);
40515             return;
40516           }
40517 
40518           PERFETTO_ELOG(
40519               "Consumer session for backend type type=%d forbidden, "
40520               "consumer will disconnect",
40521               backends_[backend_id].type);
40522 
40523           auto* consumer = FindConsumer(session_id);
40524           if (!consumer)
40525             return;
40526 
40527           consumer->OnDisconnect();
40528         });
40529       };
40530       policy_->ShouldAllowConsumerSession(args);
40531       return;
40532     }
40533     PERFETTO_DFATAL("Not reached");
40534   });
40535 
40536   return std::unique_ptr<TracingSession>(
40537       new TracingSessionImpl(this, session_id, requested_backend_type));
40538 }
40539 
InitializeInstance(const TracingInitArgs & args)40540 void TracingMuxerImpl::InitializeInstance(const TracingInitArgs& args) {
40541   if (instance_ != TracingMuxerFake::Get())
40542     PERFETTO_FATAL("Tracing already initialized");
40543   new TracingMuxerImpl(args);
40544 }
40545 
40546 TracingMuxer::~TracingMuxer() = default;
40547 
40548 static_assert(std::is_same<internal::BufferId, BufferID>::value,
40549               "public's BufferId and tracing/core's BufferID diverged");
40550 
40551 }  // namespace internal
40552 }  // namespace perfetto
40553 // gen_amalgamated begin source: src/tracing/internal/track_event_internal.cc
40554 // gen_amalgamated begin header: include/perfetto/tracing/internal/track_event_interned_fields.h
40555 /*
40556  * Copyright (C) 2021 The Android Open Source Project
40557  *
40558  * Licensed under the Apache License, Version 2.0 (the "License");
40559  * you may not use this file except in compliance with the License.
40560  * You may obtain a copy of the License at
40561  *
40562  *      http://www.apache.org/licenses/LICENSE-2.0
40563  *
40564  * Unless required by applicable law or agreed to in writing, software
40565  * distributed under the License is distributed on an "AS IS" BASIS,
40566  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
40567  * See the License for the specific language governing permissions and
40568  * limitations under the License.
40569  */
40570 
40571 // gen_amalgamated expanded: #include "perfetto/base/export.h"
40572 // gen_amalgamated expanded: #include "perfetto/tracing/track_event_interned_data_index.h"
40573 
40574 #ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_INTERNED_FIELDS_H_
40575 #define INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_INTERNED_FIELDS_H_
40576 
40577 namespace perfetto {
40578 namespace internal {
40579 
40580 // These helpers are exposed here to allow Chromium-without-client library
40581 // to share the interning buffers with Perfetto internals (e.g.
40582 // perfetto::TracedValue implementation).
40583 
40584 struct PERFETTO_EXPORT InternedEventCategory
40585     : public TrackEventInternedDataIndex<
40586           InternedEventCategory,
40587           perfetto::protos::pbzero::InternedData::kEventCategoriesFieldNumber,
40588           const char*,
40589           SmallInternedDataTraits> {
40590   ~InternedEventCategory() override;
40591 
40592   static void Add(protos::pbzero::InternedData* interned_data,
40593                   size_t iid,
40594                   const char* value,
40595                   size_t length);
40596 };
40597 
40598 struct PERFETTO_EXPORT InternedEventName
40599     : public TrackEventInternedDataIndex<
40600           InternedEventName,
40601           perfetto::protos::pbzero::InternedData::kEventNamesFieldNumber,
40602           const char*,
40603           SmallInternedDataTraits> {
40604   ~InternedEventName() override;
40605 
40606   static void Add(protos::pbzero::InternedData* interned_data,
40607                   size_t iid,
40608                   const char* value);
40609 };
40610 
40611 struct PERFETTO_EXPORT InternedDebugAnnotationName
40612     : public TrackEventInternedDataIndex<
40613           InternedDebugAnnotationName,
40614           perfetto::protos::pbzero::InternedData::
40615               kDebugAnnotationNamesFieldNumber,
40616           const char*,
40617           SmallInternedDataTraits> {
40618   ~InternedDebugAnnotationName() override;
40619 
40620   static void Add(protos::pbzero::InternedData* interned_data,
40621                   size_t iid,
40622                   const char* value);
40623 };
40624 
40625 }  // namespace internal
40626 }  // namespace perfetto
40627 
40628 #endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_INTERNED_FIELDS_H_
40629 // gen_amalgamated begin header: gen/protos/perfetto/common/track_event_descriptor.pbzero.h
40630 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
40631 
40632 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACK_EVENT_DESCRIPTOR_PROTO_H_
40633 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACK_EVENT_DESCRIPTOR_PROTO_H_
40634 
40635 #include <stddef.h>
40636 #include <stdint.h>
40637 
40638 // gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
40639 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
40640 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
40641 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
40642 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
40643 
40644 namespace perfetto {
40645 namespace protos {
40646 namespace pbzero {
40647 
40648 class TrackEventCategory;
40649 
40650 class TrackEventDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
40651  public:
TrackEventDescriptor_Decoder(const uint8_t * data,size_t len)40652   TrackEventDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TrackEventDescriptor_Decoder(const std::string & raw)40653   explicit TrackEventDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
TrackEventDescriptor_Decoder(const::protozero::ConstBytes & raw)40654   explicit TrackEventDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_available_categories() const40655   bool has_available_categories() const { return at<1>().valid(); }
available_categories() const40656   ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> available_categories() const { return GetRepeated<::protozero::ConstBytes>(1); }
40657 };
40658 
40659 class TrackEventDescriptor : public ::protozero::Message {
40660  public:
40661   using Decoder = TrackEventDescriptor_Decoder;
40662   enum : int32_t {
40663     kAvailableCategoriesFieldNumber = 1,
40664   };
40665 
40666   using FieldMetadata_AvailableCategories =
40667     ::protozero::proto_utils::FieldMetadata<
40668       1,
40669       ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
40670       ::protozero::proto_utils::ProtoSchemaType::kMessage,
40671       TrackEventCategory,
40672       TrackEventDescriptor>;
40673 
40674   // Ceci n'est pas une pipe.
40675   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
40676   // type (and users are expected to use it as such, hence kCamelCase name).
40677   // It is declared as a function to keep protozero bindings header-only as
40678   // inline constexpr variables are not available until C++17 (while inline
40679   // functions are).
40680   // TODO(altimin): Use inline variable instead after adopting C++17.
kAvailableCategories()40681   static constexpr FieldMetadata_AvailableCategories kAvailableCategories() { return {}; }
add_available_categories()40682   template <typename T = TrackEventCategory> T* add_available_categories() {
40683     return BeginNestedMessage<T>(1);
40684   }
40685 
40686 };
40687 
40688 class TrackEventCategory_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
40689  public:
TrackEventCategory_Decoder(const uint8_t * data,size_t len)40690   TrackEventCategory_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TrackEventCategory_Decoder(const std::string & raw)40691   explicit TrackEventCategory_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
TrackEventCategory_Decoder(const::protozero::ConstBytes & raw)40692   explicit TrackEventCategory_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_name() const40693   bool has_name() const { return at<1>().valid(); }
name() const40694   ::protozero::ConstChars name() const { return at<1>().as_string(); }
has_description() const40695   bool has_description() const { return at<2>().valid(); }
description() const40696   ::protozero::ConstChars description() const { return at<2>().as_string(); }
has_tags() const40697   bool has_tags() const { return at<3>().valid(); }
tags() const40698   ::protozero::RepeatedFieldIterator<::protozero::ConstChars> tags() const { return GetRepeated<::protozero::ConstChars>(3); }
40699 };
40700 
40701 class TrackEventCategory : public ::protozero::Message {
40702  public:
40703   using Decoder = TrackEventCategory_Decoder;
40704   enum : int32_t {
40705     kNameFieldNumber = 1,
40706     kDescriptionFieldNumber = 2,
40707     kTagsFieldNumber = 3,
40708   };
40709 
40710   using FieldMetadata_Name =
40711     ::protozero::proto_utils::FieldMetadata<
40712       1,
40713       ::protozero::proto_utils::RepetitionType::kNotRepeated,
40714       ::protozero::proto_utils::ProtoSchemaType::kString,
40715       std::string,
40716       TrackEventCategory>;
40717 
40718   // Ceci n'est pas une pipe.
40719   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
40720   // type (and users are expected to use it as such, hence kCamelCase name).
40721   // It is declared as a function to keep protozero bindings header-only as
40722   // inline constexpr variables are not available until C++17 (while inline
40723   // functions are).
40724   // TODO(altimin): Use inline variable instead after adopting C++17.
kName()40725   static constexpr FieldMetadata_Name kName() { return {}; }
set_name(const char * data,size_t size)40726   void set_name(const char* data, size_t size) {
40727     AppendBytes(FieldMetadata_Name::kFieldId, data, size);
40728   }
set_name(std::string value)40729   void set_name(std::string value) {
40730     static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
40731     // Call the appropriate protozero::Message::Append(field_id, ...)
40732     // method based on the type of the field.
40733     ::protozero::internal::FieldWriter<
40734       ::protozero::proto_utils::ProtoSchemaType::kString>
40735         ::Append(*this, field_id, value);
40736   }
40737 
40738   using FieldMetadata_Description =
40739     ::protozero::proto_utils::FieldMetadata<
40740       2,
40741       ::protozero::proto_utils::RepetitionType::kNotRepeated,
40742       ::protozero::proto_utils::ProtoSchemaType::kString,
40743       std::string,
40744       TrackEventCategory>;
40745 
40746   // Ceci n'est pas une pipe.
40747   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
40748   // type (and users are expected to use it as such, hence kCamelCase name).
40749   // It is declared as a function to keep protozero bindings header-only as
40750   // inline constexpr variables are not available until C++17 (while inline
40751   // functions are).
40752   // TODO(altimin): Use inline variable instead after adopting C++17.
kDescription()40753   static constexpr FieldMetadata_Description kDescription() { return {}; }
set_description(const char * data,size_t size)40754   void set_description(const char* data, size_t size) {
40755     AppendBytes(FieldMetadata_Description::kFieldId, data, size);
40756   }
set_description(std::string value)40757   void set_description(std::string value) {
40758     static constexpr uint32_t field_id = FieldMetadata_Description::kFieldId;
40759     // Call the appropriate protozero::Message::Append(field_id, ...)
40760     // method based on the type of the field.
40761     ::protozero::internal::FieldWriter<
40762       ::protozero::proto_utils::ProtoSchemaType::kString>
40763         ::Append(*this, field_id, value);
40764   }
40765 
40766   using FieldMetadata_Tags =
40767     ::protozero::proto_utils::FieldMetadata<
40768       3,
40769       ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
40770       ::protozero::proto_utils::ProtoSchemaType::kString,
40771       std::string,
40772       TrackEventCategory>;
40773 
40774   // Ceci n'est pas une pipe.
40775   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
40776   // type (and users are expected to use it as such, hence kCamelCase name).
40777   // It is declared as a function to keep protozero bindings header-only as
40778   // inline constexpr variables are not available until C++17 (while inline
40779   // functions are).
40780   // TODO(altimin): Use inline variable instead after adopting C++17.
kTags()40781   static constexpr FieldMetadata_Tags kTags() { return {}; }
add_tags(const char * data,size_t size)40782   void add_tags(const char* data, size_t size) {
40783     AppendBytes(FieldMetadata_Tags::kFieldId, data, size);
40784   }
add_tags(std::string value)40785   void add_tags(std::string value) {
40786     static constexpr uint32_t field_id = FieldMetadata_Tags::kFieldId;
40787     // Call the appropriate protozero::Message::Append(field_id, ...)
40788     // method based on the type of the field.
40789     ::protozero::internal::FieldWriter<
40790       ::protozero::proto_utils::ProtoSchemaType::kString>
40791         ::Append(*this, field_id, value);
40792   }
40793 };
40794 
40795 } // Namespace.
40796 } // Namespace.
40797 } // Namespace.
40798 #endif  // Include guard.
40799 /*
40800  * Copyright (C) 2019 The Android Open Source Project
40801  *
40802  * Licensed under the Apache License, Version 2.0 (the "License");
40803  * you may not use this file except in compliance with the License.
40804  * You may obtain a copy of the License at
40805  *
40806  *      http://www.apache.org/licenses/LICENSE-2.0
40807  *
40808  * Unless required by applicable law or agreed to in writing, software
40809  * distributed under the License is distributed on an "AS IS" BASIS,
40810  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
40811  * See the License for the specific language governing permissions and
40812  * limitations under the License.
40813  */
40814 
40815 // gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_internal.h"
40816 
40817 // gen_amalgamated expanded: #include "perfetto/base/proc_utils.h"
40818 // gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
40819 // gen_amalgamated expanded: #include "perfetto/base/time.h"
40820 // gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
40821 // gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_interned_fields.h"
40822 // gen_amalgamated expanded: #include "perfetto/tracing/track_event.h"
40823 // gen_amalgamated expanded: #include "perfetto/tracing/track_event_category_registry.h"
40824 // gen_amalgamated expanded: #include "perfetto/tracing/track_event_interned_data_index.h"
40825 // gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
40826 // gen_amalgamated expanded: #include "protos/perfetto/common/track_event_descriptor.pbzero.h"
40827 // gen_amalgamated expanded: #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
40828 // gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet_defaults.pbzero.h"
40829 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
40830 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_descriptor.pbzero.h"
40831 
40832 namespace perfetto {
40833 
40834 TrackEventSessionObserver::~TrackEventSessionObserver() = default;
OnSetup(const DataSourceBase::SetupArgs &)40835 void TrackEventSessionObserver::OnSetup(const DataSourceBase::SetupArgs&) {}
OnStart(const DataSourceBase::StartArgs &)40836 void TrackEventSessionObserver::OnStart(const DataSourceBase::StartArgs&) {}
OnStop(const DataSourceBase::StopArgs &)40837 void TrackEventSessionObserver::OnStop(const DataSourceBase::StopArgs&) {}
40838 
40839 namespace internal {
40840 
40841 BaseTrackEventInternedDataIndex::~BaseTrackEventInternedDataIndex() = default;
40842 
40843 namespace {
40844 
40845 std::atomic<perfetto::base::PlatformThreadId> g_main_thread;
40846 static constexpr const char kLegacySlowPrefix[] = "disabled-by-default-";
40847 static constexpr const char kSlowTag[] = "slow";
40848 static constexpr const char kDebugTag[] = "debug";
40849 
ForEachObserver(std::function<bool (TrackEventSessionObserver * &)> callback)40850 void ForEachObserver(
40851     std::function<bool(TrackEventSessionObserver*&)> callback) {
40852   // Session observers, shared by all track event data source instances.
40853   static constexpr int kMaxObservers = 8;
40854   static std::recursive_mutex* mutex = new std::recursive_mutex{};  // Leaked.
40855   static std::array<TrackEventSessionObserver*, kMaxObservers> observers{};
40856   std::unique_lock<std::recursive_mutex> lock(*mutex);
40857   for (auto& o : observers) {
40858     if (!callback(o))
40859       break;
40860   }
40861 }
40862 
40863 enum class MatchType { kExact, kPattern };
40864 
NameMatchesPattern(const std::string & pattern,const std::string & name,MatchType match_type)40865 bool NameMatchesPattern(const std::string& pattern,
40866                         const std::string& name,
40867                         MatchType match_type) {
40868   // To avoid pulling in all of std::regex, for now we only support a single "*"
40869   // wildcard at the end of the pattern.
40870   size_t i = pattern.find('*');
40871   if (i != std::string::npos) {
40872     PERFETTO_DCHECK(i == pattern.size() - 1);
40873     if (match_type != MatchType::kPattern)
40874       return false;
40875     return name.substr(0, i) == pattern.substr(0, i);
40876   }
40877   return name == pattern;
40878 }
40879 
NameMatchesPatternList(const std::vector<std::string> & patterns,const std::string & name,MatchType match_type)40880 bool NameMatchesPatternList(const std::vector<std::string>& patterns,
40881                             const std::string& name,
40882                             MatchType match_type) {
40883   for (const auto& pattern : patterns) {
40884     if (NameMatchesPattern(pattern, name, match_type))
40885       return true;
40886   }
40887   return false;
40888 }
40889 
40890 }  // namespace
40891 
40892 // static
40893 const Track TrackEventInternal::kDefaultTrack{};
40894 
40895 // static
40896 std::atomic<int> TrackEventInternal::session_count_{};
40897 
40898 // static
Initialize(const TrackEventCategoryRegistry & registry,bool (* register_data_source)(const DataSourceDescriptor &))40899 bool TrackEventInternal::Initialize(
40900     const TrackEventCategoryRegistry& registry,
40901     bool (*register_data_source)(const DataSourceDescriptor&)) {
40902   if (!g_main_thread)
40903     g_main_thread = perfetto::base::GetThreadId();
40904 
40905   DataSourceDescriptor dsd;
40906   dsd.set_name("track_event");
40907 
40908   protozero::HeapBuffered<protos::pbzero::TrackEventDescriptor> ted;
40909   for (size_t i = 0; i < registry.category_count(); i++) {
40910     auto category = registry.GetCategory(i);
40911     // Don't register group categories.
40912     if (category->IsGroup())
40913       continue;
40914     auto cat = ted->add_available_categories();
40915     cat->set_name(category->name);
40916     if (category->description)
40917       cat->set_description(category->description);
40918     for (const auto& tag : category->tags) {
40919       if (tag)
40920         cat->add_tags(tag);
40921     }
40922     // Disabled-by-default categories get a "slow" tag.
40923     if (!strncmp(category->name, kLegacySlowPrefix, strlen(kLegacySlowPrefix)))
40924       cat->add_tags(kSlowTag);
40925   }
40926   dsd.set_track_event_descriptor_raw(ted.SerializeAsString());
40927 
40928   return register_data_source(dsd);
40929 }
40930 
40931 // static
AddSessionObserver(TrackEventSessionObserver * observer)40932 bool TrackEventInternal::AddSessionObserver(
40933     TrackEventSessionObserver* observer) {
40934   bool result = false;
40935   ForEachObserver([&](TrackEventSessionObserver*& o) {
40936     if (!o) {
40937       o = observer;
40938       result = true;
40939       return false;
40940     }
40941     return true;
40942   });
40943   return result;
40944 }
40945 
40946 // static
RemoveSessionObserver(TrackEventSessionObserver * observer)40947 void TrackEventInternal::RemoveSessionObserver(
40948     TrackEventSessionObserver* observer) {
40949   ForEachObserver([&](TrackEventSessionObserver*& o) {
40950     if (o == observer) {
40951       o = nullptr;
40952       return false;
40953     }
40954     return true;
40955   });
40956 }
40957 
40958 // static
EnableTracing(const TrackEventCategoryRegistry & registry,const protos::gen::TrackEventConfig & config,const DataSourceBase::SetupArgs & args)40959 void TrackEventInternal::EnableTracing(
40960     const TrackEventCategoryRegistry& registry,
40961     const protos::gen::TrackEventConfig& config,
40962     const DataSourceBase::SetupArgs& args) {
40963   for (size_t i = 0; i < registry.category_count(); i++) {
40964     if (IsCategoryEnabled(registry, config, *registry.GetCategory(i)))
40965       registry.EnableCategoryForInstance(i, args.internal_instance_index);
40966   }
40967   ForEachObserver([&](TrackEventSessionObserver*& o) {
40968     if (o)
40969       o->OnSetup(args);
40970     return true;
40971   });
40972 }
40973 
40974 // static
OnStart(const DataSourceBase::StartArgs & args)40975 void TrackEventInternal::OnStart(const DataSourceBase::StartArgs& args) {
40976   session_count_.fetch_add(1);
40977   ForEachObserver([&](TrackEventSessionObserver*& o) {
40978     if (o)
40979       o->OnStart(args);
40980     return true;
40981   });
40982 }
40983 
40984 // static
DisableTracing(const TrackEventCategoryRegistry & registry,const DataSourceBase::StopArgs & args)40985 void TrackEventInternal::DisableTracing(
40986     const TrackEventCategoryRegistry& registry,
40987     const DataSourceBase::StopArgs& args) {
40988   ForEachObserver([&](TrackEventSessionObserver*& o) {
40989     if (o)
40990       o->OnStop(args);
40991     return true;
40992   });
40993   for (size_t i = 0; i < registry.category_count(); i++)
40994     registry.DisableCategoryForInstance(i, args.internal_instance_index);
40995 }
40996 
40997 // static
IsCategoryEnabled(const TrackEventCategoryRegistry & registry,const protos::gen::TrackEventConfig & config,const Category & category)40998 bool TrackEventInternal::IsCategoryEnabled(
40999     const TrackEventCategoryRegistry& registry,
41000     const protos::gen::TrackEventConfig& config,
41001     const Category& category) {
41002   // If this is a group category, check if any of its constituent categories are
41003   // enabled. If so, then this one is enabled too.
41004   if (category.IsGroup()) {
41005     bool result = false;
41006     category.ForEachGroupMember([&](const char* member_name, size_t name_size) {
41007       for (size_t i = 0; i < registry.category_count(); i++) {
41008         const auto ref_category = registry.GetCategory(i);
41009         // Groups can't refer to other groups.
41010         if (ref_category->IsGroup())
41011           continue;
41012         // Require an exact match.
41013         if (ref_category->name_size() != name_size ||
41014             strncmp(ref_category->name, member_name, name_size)) {
41015           continue;
41016         }
41017         if (IsCategoryEnabled(registry, config, *ref_category)) {
41018           result = true;
41019           // Break ForEachGroupMember() loop.
41020           return false;
41021         }
41022         break;
41023       }
41024       // No match? Must be a dynamic category.
41025       DynamicCategory dyn_category(std::string(member_name, name_size));
41026       Category ref_category{Category::FromDynamicCategory(dyn_category)};
41027       if (IsCategoryEnabled(registry, config, ref_category)) {
41028         result = true;
41029         // Break ForEachGroupMember() loop.
41030         return false;
41031       }
41032       // No match found => keep iterating.
41033       return true;
41034     });
41035     return result;
41036   }
41037 
41038   auto has_matching_tag = [&](std::function<bool(const char*)> matcher) {
41039     for (const auto& tag : category.tags) {
41040       if (!tag)
41041         break;
41042       if (matcher(tag))
41043         return true;
41044     }
41045     // Legacy "disabled-by-default" categories automatically get the "slow" tag.
41046     if (!strncmp(category.name, kLegacySlowPrefix, strlen(kLegacySlowPrefix)) &&
41047         matcher(kSlowTag)) {
41048       return true;
41049     }
41050     return false;
41051   };
41052 
41053   // First try exact matches, then pattern matches.
41054   const std::array<MatchType, 2> match_types = {
41055       {MatchType::kExact, MatchType::kPattern}};
41056   for (auto match_type : match_types) {
41057     // 1. Enabled categories.
41058     if (NameMatchesPatternList(config.enabled_categories(), category.name,
41059                                match_type)) {
41060       return true;
41061     }
41062 
41063     // 2. Enabled tags.
41064     if (has_matching_tag([&](const char* tag) {
41065           return NameMatchesPatternList(config.enabled_tags(), tag, match_type);
41066         })) {
41067       return true;
41068     }
41069 
41070     // 3. Disabled categories.
41071     if (NameMatchesPatternList(config.disabled_categories(), category.name,
41072                                match_type)) {
41073       return false;
41074     }
41075 
41076     // 4. Disabled tags.
41077     if (has_matching_tag([&](const char* tag) {
41078           if (config.disabled_tags_size()) {
41079             return NameMatchesPatternList(config.disabled_tags(), tag,
41080                                           match_type);
41081           } else {
41082             // The "slow" and "debug" tags are disabled by default.
41083             return NameMatchesPattern(kSlowTag, tag, match_type) ||
41084                    NameMatchesPattern(kDebugTag, tag, match_type);
41085           }
41086         })) {
41087       return false;
41088     }
41089   }
41090 
41091   // If nothing matched, enable the category by default.
41092   return true;
41093 }
41094 
41095 // static
GetTimeNs()41096 uint64_t TrackEventInternal::GetTimeNs() {
41097   if (GetClockId() == protos::pbzero::BUILTIN_CLOCK_BOOTTIME)
41098     return static_cast<uint64_t>(perfetto::base::GetBootTimeNs().count());
41099   PERFETTO_DCHECK(GetClockId() == protos::pbzero::BUILTIN_CLOCK_MONOTONIC);
41100   return static_cast<uint64_t>(perfetto::base::GetWallTimeNs().count());
41101 }
41102 
41103 // static
GetSessionCount()41104 int TrackEventInternal::GetSessionCount() {
41105   return session_count_.load();
41106 }
41107 
41108 // static
ResetIncrementalState(TraceWriterBase * trace_writer,uint64_t timestamp)41109 void TrackEventInternal::ResetIncrementalState(TraceWriterBase* trace_writer,
41110                                                uint64_t timestamp) {
41111   auto default_track = ThreadTrack::Current();
41112   {
41113     // Mark any incremental state before this point invalid. Also set up
41114     // defaults so that we don't need to repeat constant data for each packet.
41115     auto packet = NewTracePacket(
41116         trace_writer, timestamp,
41117         protos::pbzero::TracePacket::SEQ_INCREMENTAL_STATE_CLEARED);
41118     auto defaults = packet->set_trace_packet_defaults();
41119     defaults->set_timestamp_clock_id(GetClockId());
41120 
41121     // Establish the default track for this event sequence.
41122     auto track_defaults = defaults->set_track_event_defaults();
41123     track_defaults->set_track_uuid(default_track.uuid);
41124   }
41125 
41126   // Every thread should write a descriptor for its default track, because most
41127   // trace points won't explicitly reference it.
41128   WriteTrackDescriptor(default_track, trace_writer);
41129 
41130   // Additionally the main thread should dump the process descriptor.
41131   if (perfetto::base::GetThreadId() == g_main_thread)
41132     WriteTrackDescriptor(ProcessTrack::Current(), trace_writer);
41133 }
41134 
41135 // static
41136 protozero::MessageHandle<protos::pbzero::TracePacket>
NewTracePacket(TraceWriterBase * trace_writer,uint64_t timestamp,uint32_t seq_flags)41137 TrackEventInternal::NewTracePacket(TraceWriterBase* trace_writer,
41138                                    uint64_t timestamp,
41139                                    uint32_t seq_flags) {
41140   auto packet = trace_writer->NewTracePacket();
41141   packet->set_timestamp(timestamp);
41142   // TODO(skyostil): Stop emitting this for every event once the trace
41143   // processor understands trace packet defaults.
41144   if (GetClockId() != protos::pbzero::BUILTIN_CLOCK_BOOTTIME)
41145     packet->set_timestamp_clock_id(GetClockId());
41146   packet->set_sequence_flags(seq_flags);
41147   return packet;
41148 }
41149 
41150 // static
WriteEvent(TraceWriterBase * trace_writer,TrackEventIncrementalState * incr_state,const Category * category,const char * name,perfetto::protos::pbzero::TrackEvent::Type type,uint64_t timestamp)41151 EventContext TrackEventInternal::WriteEvent(
41152     TraceWriterBase* trace_writer,
41153     TrackEventIncrementalState* incr_state,
41154     const Category* category,
41155     const char* name,
41156     perfetto::protos::pbzero::TrackEvent::Type type,
41157     uint64_t timestamp) {
41158   PERFETTO_DCHECK(g_main_thread);
41159   PERFETTO_DCHECK(!incr_state->was_cleared);
41160 
41161   auto packet = NewTracePacket(trace_writer, timestamp);
41162   EventContext ctx(std::move(packet), incr_state);
41163 
41164   auto track_event = ctx.event();
41165   if (type != protos::pbzero::TrackEvent::TYPE_UNSPECIFIED)
41166     track_event->set_type(type);
41167 
41168   // We assume that |category| and |name| point to strings with static lifetime.
41169   // This means we can use their addresses as interning keys.
41170   // TODO(skyostil): Intern categories at compile time.
41171   if (category && type != protos::pbzero::TrackEvent::TYPE_SLICE_END &&
41172       type != protos::pbzero::TrackEvent::TYPE_COUNTER) {
41173     category->ForEachGroupMember(
41174         [&](const char* member_name, size_t name_size) {
41175           size_t category_iid =
41176               InternedEventCategory::Get(&ctx, member_name, name_size);
41177           track_event->add_category_iids(category_iid);
41178           return true;
41179         });
41180   }
41181   if (name && type != protos::pbzero::TrackEvent::TYPE_SLICE_END) {
41182     size_t name_iid = InternedEventName::Get(&ctx, name);
41183     track_event->set_name_iid(name_iid);
41184   }
41185   return ctx;
41186 }
41187 
41188 // static
AddDebugAnnotation(perfetto::EventContext * event_ctx,const char * name)41189 protos::pbzero::DebugAnnotation* TrackEventInternal::AddDebugAnnotation(
41190     perfetto::EventContext* event_ctx,
41191     const char* name) {
41192   auto annotation = event_ctx->event()->add_debug_annotations();
41193   annotation->set_name_iid(InternedDebugAnnotationName::Get(event_ctx, name));
41194   return annotation;
41195 }
41196 
41197 }  // namespace internal
41198 }  // namespace perfetto
41199 // gen_amalgamated begin source: src/tracing/internal/track_event_interned_fields.cc
41200 /*
41201  * Copyright (C) 2021 The Android Open Source Project
41202  *
41203  * Licensed under the Apache License, Version 2.0 (the "License");
41204  * you may not use this file except in compliance with the License.
41205  * You may obtain a copy of the License at
41206  *
41207  *      http://www.apache.org/licenses/LICENSE-2.0
41208  *
41209  * Unless required by applicable law or agreed to in writing, software
41210  * distributed under the License is distributed on an "AS IS" BASIS,
41211  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
41212  * See the License for the specific language governing permissions and
41213  * limitations under the License.
41214  */
41215 
41216 // gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_interned_fields.h"
41217 
41218 namespace perfetto {
41219 namespace internal {
41220 
41221 InternedEventCategory::~InternedEventCategory() = default;
41222 
41223 // static
Add(protos::pbzero::InternedData * interned_data,size_t iid,const char * value,size_t length)41224 void InternedEventCategory::Add(protos::pbzero::InternedData* interned_data,
41225                                 size_t iid,
41226                                 const char* value,
41227                                 size_t length) {
41228   auto category = interned_data->add_event_categories();
41229   category->set_iid(iid);
41230   category->set_name(value, length);
41231 }
41232 
41233 InternedEventName::~InternedEventName() = default;
41234 
41235 // static
Add(protos::pbzero::InternedData * interned_data,size_t iid,const char * value)41236 void InternedEventName::Add(protos::pbzero::InternedData* interned_data,
41237                             size_t iid,
41238                             const char* value) {
41239   auto name = interned_data->add_event_names();
41240   name->set_iid(iid);
41241   name->set_name(value);
41242 }
41243 
41244 InternedDebugAnnotationName::~InternedDebugAnnotationName() = default;
41245 
41246 // static
Add(protos::pbzero::InternedData * interned_data,size_t iid,const char * value)41247 void InternedDebugAnnotationName::Add(
41248     protos::pbzero::InternedData* interned_data,
41249     size_t iid,
41250     const char* value) {
41251   auto name = interned_data->add_debug_annotation_names();
41252   name->set_iid(iid);
41253   name->set_name(value);
41254 }
41255 
41256 }  // namespace internal
41257 }  // namespace perfetto
41258 // gen_amalgamated begin source: src/tracing/platform.cc
41259 /*
41260  * Copyright (C) 2019 The Android Open Source Project
41261  *
41262  * Licensed under the Apache License, Version 2.0 (the "License");
41263  * you may not use this file except in compliance with the License.
41264  * You may obtain a copy of the License at
41265  *
41266  *      http://www.apache.org/licenses/LICENSE-2.0
41267  *
41268  * Unless required by applicable law or agreed to in writing, software
41269  * distributed under the License is distributed on an "AS IS" BASIS,
41270  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
41271  * See the License for the specific language governing permissions and
41272  * limitations under the License.
41273  */
41274 
41275 // gen_amalgamated expanded: #include "perfetto/tracing/platform.h"
41276 // gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_tls.h"
41277 // gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
41278 
41279 namespace perfetto {
41280 
41281 PlatformThreadLocalObject::~PlatformThreadLocalObject() = default;
41282 Platform::~Platform() = default;
41283 
41284 // static
41285 std::unique_ptr<PlatformThreadLocalObject>
CreateInstance()41286 PlatformThreadLocalObject::CreateInstance() {
41287   return std::unique_ptr<PlatformThreadLocalObject>(new internal::TracingTLS());
41288 }
41289 
41290 }  // namespace perfetto
41291 // gen_amalgamated begin source: src/tracing/traced_value.cc
41292 /*
41293  * Copyright (C) 2021 The Android Open Source Project
41294  *
41295  * Licensed under the Apache License, Version 2.0 (the "License");
41296  * you may not use this file except in compliance with the License.
41297  * You may obtain a copy of the License at
41298  *
41299  *      http://www.apache.org/licenses/LICENSE-2.0
41300  *
41301  * Unless required by applicable law or agreed to in writing, software
41302  * distributed under the License is distributed on an "AS IS" BASIS,
41303  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
41304  * See the License for the specific language governing permissions and
41305  * limitations under the License.
41306  */
41307 
41308 // gen_amalgamated expanded: #include "perfetto/tracing/traced_value.h"
41309 
41310 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
41311 // gen_amalgamated expanded: #include "perfetto/tracing/debug_annotation.h"
41312 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
41313 
41314 namespace perfetto {
41315 
41316 namespace internal {
41317 
CreateTracedValueFromProto(protos::pbzero::DebugAnnotation * context)41318 TracedValue CreateTracedValueFromProto(
41319     protos::pbzero::DebugAnnotation* context) {
41320   return TracedValue::CreateFromProto(context);
41321 }
41322 
41323 }  // namespace internal
41324 
41325 // static
CreateFromProto(protos::pbzero::DebugAnnotation * context)41326 TracedValue TracedValue::CreateFromProto(
41327     protos::pbzero::DebugAnnotation* context) {
41328   return TracedValue(context, nullptr);
41329 }
41330 
WriteInt64(int64_t value)41331 void TracedValue::WriteInt64(int64_t value) && {
41332   PERFETTO_DCHECK(checked_scope_.is_active());
41333   context_->set_int_value(value);
41334 }
41335 
WriteUInt64(uint64_t value)41336 void TracedValue::WriteUInt64(uint64_t value) && {
41337   PERFETTO_DCHECK(checked_scope_.is_active());
41338   context_->set_uint_value(value);
41339 }
41340 
WriteDouble(double value)41341 void TracedValue::WriteDouble(double value) && {
41342   PERFETTO_DCHECK(checked_scope_.is_active());
41343   context_->set_double_value(value);
41344 }
41345 
WriteBoolean(bool value)41346 void TracedValue::WriteBoolean(bool value) && {
41347   PERFETTO_DCHECK(checked_scope_.is_active());
41348   context_->set_bool_value(value);
41349 }
41350 
WriteString(const char * value)41351 void TracedValue::WriteString(const char* value) && {
41352   PERFETTO_DCHECK(checked_scope_.is_active());
41353   context_->set_string_value(value);
41354 }
41355 
WriteString(const char * value,size_t len)41356 void TracedValue::WriteString(const char* value, size_t len) && {
41357   PERFETTO_DCHECK(checked_scope_.is_active());
41358   context_->set_string_value(value, len);
41359 }
41360 
WriteString(const std::string & value)41361 void TracedValue::WriteString(const std::string& value) && {
41362   PERFETTO_DCHECK(checked_scope_.is_active());
41363   context_->set_string_value(value);
41364 }
41365 
WritePointer(const void * value)41366 void TracedValue::WritePointer(const void* value) && {
41367   PERFETTO_DCHECK(checked_scope_.is_active());
41368   context_->set_pointer_value(reinterpret_cast<uint64_t>(value));
41369 }
41370 
WriteDictionary()41371 TracedDictionary TracedValue::WriteDictionary() && {
41372   // Note: this passes |checked_scope_.is_active_| bit to the parent to be
41373   // picked up later by the new TracedDictionary.
41374   PERFETTO_DCHECK(checked_scope_.is_active());
41375   checked_scope_.Reset();
41376 
41377   PERFETTO_DCHECK(!context_->is_finalized());
41378   return TracedDictionary(context_, checked_scope_.parent_scope());
41379 }
41380 
WriteArray()41381 TracedArray TracedValue::WriteArray() && {
41382   // Note: this passes |checked_scope_.is_active_| bit to the parent to be
41383   // picked up later by the new TracedDictionary.
41384   PERFETTO_DCHECK(checked_scope_.is_active());
41385   checked_scope_.Reset();
41386 
41387   PERFETTO_DCHECK(!context_->is_finalized());
41388   return TracedArray(context_, checked_scope_.parent_scope());
41389 }
41390 
AppendItem()41391 TracedValue TracedArray::AppendItem() {
41392   PERFETTO_DCHECK(checked_scope_.is_active());
41393   return TracedValue(context_->add_array_values(), &checked_scope_);
41394 }
41395 
AppendDictionary()41396 TracedDictionary TracedArray::AppendDictionary() {
41397   PERFETTO_DCHECK(checked_scope_.is_active());
41398   return AppendItem().WriteDictionary();
41399 }
41400 
AppendArray()41401 TracedArray TracedArray::AppendArray() {
41402   PERFETTO_DCHECK(checked_scope_.is_active());
41403   return AppendItem().WriteArray();
41404 }
41405 
AddItem(StaticString key)41406 TracedValue TracedDictionary::AddItem(StaticString key) {
41407   PERFETTO_DCHECK(checked_scope_.is_active());
41408   protos::pbzero::DebugAnnotation* item = context_->add_dict_entries();
41409   item->set_name(key.value);
41410   return TracedValue(item, &checked_scope_);
41411 }
41412 
AddItem(DynamicString key)41413 TracedValue TracedDictionary::AddItem(DynamicString key) {
41414   PERFETTO_DCHECK(checked_scope_.is_active());
41415   protos::pbzero::DebugAnnotation* item = context_->add_dict_entries();
41416   item->set_name(key.value);
41417   return TracedValue(item, &checked_scope_);
41418 }
41419 
AddDictionary(StaticString key)41420 TracedDictionary TracedDictionary::AddDictionary(StaticString key) {
41421   PERFETTO_DCHECK(checked_scope_.is_active());
41422   return AddItem(key).WriteDictionary();
41423 }
41424 
AddDictionary(DynamicString key)41425 TracedDictionary TracedDictionary::AddDictionary(DynamicString key) {
41426   PERFETTO_DCHECK(checked_scope_.is_active());
41427   return AddItem(key).WriteDictionary();
41428 }
41429 
AddArray(StaticString key)41430 TracedArray TracedDictionary::AddArray(StaticString key) {
41431   PERFETTO_DCHECK(checked_scope_.is_active());
41432   return AddItem(key).WriteArray();
41433 }
41434 
AddArray(DynamicString key)41435 TracedArray TracedDictionary::AddArray(DynamicString key) {
41436   PERFETTO_DCHECK(checked_scope_.is_active());
41437   return AddItem(key).WriteArray();
41438 }
41439 
41440 }  // namespace perfetto
41441 // gen_amalgamated begin source: src/tracing/tracing.cc
41442 /*
41443  * Copyright (C) 2019 The Android Open Source Project
41444  *
41445  * Licensed under the Apache License, Version 2.0 (the "License");
41446  * you may not use this file except in compliance with the License.
41447  * You may obtain a copy of the License at
41448  *
41449  *      http://www.apache.org/licenses/LICENSE-2.0
41450  *
41451  * Unless required by applicable law or agreed to in writing, software
41452  * distributed under the License is distributed on an "AS IS" BASIS,
41453  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
41454  * See the License for the specific language governing permissions and
41455  * limitations under the License.
41456  */
41457 
41458 // gen_amalgamated expanded: #include "perfetto/tracing/tracing.h"
41459 
41460 #include <atomic>
41461 #include <condition_variable>
41462 #include <mutex>
41463 
41464 // gen_amalgamated expanded: #include "perfetto/ext/base/waitable_event.h"
41465 // gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_internal.h"
41466 // gen_amalgamated expanded: #include "src/tracing/internal/tracing_muxer_impl.h"
41467 
41468 namespace perfetto {
41469 namespace {
41470 bool g_was_initialized = false;
41471 }
41472 
41473 // static
InitializeInternal(const TracingInitArgs & args)41474 void Tracing::InitializeInternal(const TracingInitArgs& args) {
41475   static TracingInitArgs init_args;
41476   if (g_was_initialized) {
41477     if (!(init_args == args)) {
41478       PERFETTO_ELOG(
41479           "Tracing::Initialize() called more than once with different args. "
41480           "This is not supported, only the first call will have effect.");
41481       PERFETTO_DCHECK(false);
41482     }
41483     return;
41484   }
41485 
41486   // Make sure the headers and implementation files agree on the build config.
41487   PERFETTO_CHECK(args.dcheck_is_on_ == PERFETTO_DCHECK_IS_ON());
41488   if (args.log_message_callback) {
41489     SetLogMessageCallback(args.log_message_callback);
41490   }
41491   internal::TracingMuxerImpl::InitializeInstance(args);
41492   internal::TrackRegistry::InitializeInstance();
41493   g_was_initialized = true;
41494   init_args = args;
41495 }
41496 
41497 // static
IsInitialized()41498 bool Tracing::IsInitialized() {
41499   return g_was_initialized;
41500 }
41501 
41502 //  static
NewTrace(BackendType backend)41503 std::unique_ptr<TracingSession> Tracing::NewTrace(BackendType backend) {
41504   return static_cast<internal::TracingMuxerImpl*>(internal::TracingMuxer::Get())
41505       ->CreateTracingSession(backend);
41506 }
41507 
41508 // Can be called from any thread.
FlushBlocking(uint32_t timeout_ms)41509 bool TracingSession::FlushBlocking(uint32_t timeout_ms) {
41510   std::atomic<bool> flush_result;
41511   base::WaitableEvent flush_ack;
41512 
41513   // The non blocking Flush() can be called on any thread. It does the PostTask
41514   // internally.
41515   Flush(
41516       [&flush_ack, &flush_result](bool res) {
41517         flush_result = res;
41518         flush_ack.Notify();
41519       },
41520       timeout_ms);
41521   flush_ack.Wait();
41522   return flush_result;
41523 }
41524 
ReadTraceBlocking()41525 std::vector<char> TracingSession::ReadTraceBlocking() {
41526   std::vector<char> raw_trace;
41527   std::mutex mutex;
41528   std::condition_variable cv;
41529 
41530   bool all_read = false;
41531 
41532   ReadTrace([&mutex, &raw_trace, &all_read, &cv](ReadTraceCallbackArgs cb) {
41533     raw_trace.insert(raw_trace.end(), cb.data, cb.data + cb.size);
41534     std::unique_lock<std::mutex> lock(mutex);
41535     all_read = !cb.has_more;
41536     if (all_read)
41537       cv.notify_one();
41538   });
41539 
41540   {
41541     std::unique_lock<std::mutex> lock(mutex);
41542     cv.wait(lock, [&all_read] { return all_read; });
41543   }
41544   return raw_trace;
41545 }
41546 
41547 TracingSession::GetTraceStatsCallbackArgs
GetTraceStatsBlocking()41548 TracingSession::GetTraceStatsBlocking() {
41549   std::mutex mutex;
41550   std::condition_variable cv;
41551   GetTraceStatsCallbackArgs result;
41552   bool stats_read = false;
41553 
41554   GetTraceStats(
41555       [&mutex, &result, &stats_read, &cv](GetTraceStatsCallbackArgs args) {
41556         result = std::move(args);
41557         std::unique_lock<std::mutex> lock(mutex);
41558         stats_read = true;
41559         cv.notify_one();
41560       });
41561 
41562   {
41563     std::unique_lock<std::mutex> lock(mutex);
41564     cv.wait(lock, [&stats_read] { return stats_read; });
41565   }
41566   return result;
41567 }
41568 
41569 TracingSession::QueryServiceStateCallbackArgs
QueryServiceStateBlocking()41570 TracingSession::QueryServiceStateBlocking() {
41571   std::mutex mutex;
41572   std::condition_variable cv;
41573   QueryServiceStateCallbackArgs result;
41574   bool status_read = false;
41575 
41576   QueryServiceState(
41577       [&mutex, &result, &status_read, &cv](QueryServiceStateCallbackArgs args) {
41578         result = std::move(args);
41579         std::unique_lock<std::mutex> lock(mutex);
41580         status_read = true;
41581         cv.notify_one();
41582       });
41583 
41584   {
41585     std::unique_lock<std::mutex> lock(mutex);
41586     cv.wait(lock, [&status_read] { return status_read; });
41587   }
41588   return result;
41589 }
41590 
41591 }  // namespace perfetto
41592 // gen_amalgamated begin source: src/tracing/tracing_policy.cc
41593 /*
41594  * Copyright (C) 2021 The Android Open Source Project
41595  *
41596  * Licensed under the Apache License, Version 2.0 (the "License");
41597  * you may not use this file except in compliance with the License.
41598  * You may obtain a copy of the License at
41599  *
41600  *      http://www.apache.org/licenses/LICENSE-2.0
41601  *
41602  * Unless required by applicable law or agreed to in writing, software
41603  * distributed under the License is distributed on an "AS IS" BASIS,
41604  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
41605  * See the License for the specific language governing permissions and
41606  * limitations under the License.
41607  */
41608 
41609 // gen_amalgamated expanded: #include "perfetto/tracing/tracing_policy.h"
41610 
41611 namespace perfetto {
41612 
41613 TracingPolicy::~TracingPolicy() = default;
41614 
41615 }  // namespace perfetto
41616 // gen_amalgamated begin source: src/tracing/track.cc
41617 /*
41618  * Copyright (C) 2019 The Android Open Source Project
41619  *
41620  * Licensed under the Apache License, Version 2.0 (the "License");
41621  * you may not use this file except in compliance with the License.
41622  * You may obtain a copy of the License at
41623  *
41624  *      http://www.apache.org/licenses/LICENSE-2.0
41625  *
41626  * Unless required by applicable law or agreed to in writing, software
41627  * distributed under the License is distributed on an "AS IS" BASIS,
41628  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
41629  * See the License for the specific language governing permissions and
41630  * limitations under the License.
41631  */
41632 
41633 // gen_amalgamated expanded: #include "perfetto/tracing/track.h"
41634 
41635 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
41636 // gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
41637 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
41638 // gen_amalgamated expanded: #include "perfetto/ext/base/string_splitter.h"
41639 // gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
41640 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_utils.h"
41641 // gen_amalgamated expanded: #include "perfetto/ext/base/uuid.h"
41642 // gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_data_source.h"
41643 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/counter_descriptor.gen.h"
41644 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/process_descriptor.gen.h"
41645 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/process_descriptor.pbzero.h"
41646 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/thread_descriptor.gen.h"
41647 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/thread_descriptor.pbzero.h"
41648 
41649 namespace perfetto {
41650 
41651 // static
41652 uint64_t Track::process_uuid;
41653 
Serialize() const41654 protos::gen::TrackDescriptor Track::Serialize() const {
41655   protos::gen::TrackDescriptor desc;
41656   desc.set_uuid(uuid);
41657   if (parent_uuid)
41658     desc.set_parent_uuid(parent_uuid);
41659   return desc;
41660 }
41661 
Serialize(protos::pbzero::TrackDescriptor * desc) const41662 void Track::Serialize(protos::pbzero::TrackDescriptor* desc) const {
41663   auto bytes = Serialize().SerializeAsString();
41664   desc->AppendRawProtoBytes(bytes.data(), bytes.size());
41665 }
41666 
Serialize() const41667 protos::gen::TrackDescriptor ProcessTrack::Serialize() const {
41668   auto desc = Track::Serialize();
41669   auto pd = desc.mutable_process();
41670   pd->set_pid(static_cast<int32_t>(pid));
41671 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
41672     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
41673   std::string cmdline;
41674   if (base::ReadFile("/proc/self/cmdline", &cmdline)) {
41675     // Since cmdline is a zero-terminated list of arguments, this ends up
41676     // writing just the first element, i.e., the process name, into the process
41677     // name field.
41678     pd->set_process_name(cmdline.c_str());
41679     base::StringSplitter splitter(std::move(cmdline), '\0');
41680     while (splitter.Next()) {
41681       pd->add_cmdline(
41682           std::string(splitter.cur_token(), splitter.cur_token_size()));
41683     }
41684   }
41685   // TODO(skyostil): Record command line on Windows and Mac.
41686 #endif
41687   return desc;
41688 }
41689 
Serialize(protos::pbzero::TrackDescriptor * desc) const41690 void ProcessTrack::Serialize(protos::pbzero::TrackDescriptor* desc) const {
41691   auto bytes = Serialize().SerializeAsString();
41692   desc->AppendRawProtoBytes(bytes.data(), bytes.size());
41693 }
41694 
Serialize() const41695 protos::gen::TrackDescriptor ThreadTrack::Serialize() const {
41696   auto desc = Track::Serialize();
41697   auto td = desc.mutable_thread();
41698   td->set_pid(static_cast<int32_t>(pid));
41699   td->set_tid(static_cast<int32_t>(tid));
41700   std::string thread_name;
41701   if (base::GetThreadName(thread_name))
41702     td->set_thread_name(thread_name);
41703   return desc;
41704 }
41705 
Serialize(protos::pbzero::TrackDescriptor * desc) const41706 void ThreadTrack::Serialize(protos::pbzero::TrackDescriptor* desc) const {
41707   auto bytes = Serialize().SerializeAsString();
41708   desc->AppendRawProtoBytes(bytes.data(), bytes.size());
41709 }
41710 
Serialize() const41711 protos::gen::TrackDescriptor CounterTrack::Serialize() const {
41712   auto desc = Track::Serialize();
41713   desc.set_name(name_);
41714   auto* counter = desc.mutable_counter();
41715   if (category_)
41716     counter->add_categories(category_);
41717   if (unit_ != perfetto::protos::pbzero::CounterDescriptor::UNIT_UNSPECIFIED)
41718     counter->set_unit(static_cast<protos::gen::CounterDescriptor_Unit>(unit_));
41719   if (unit_name_)
41720     counter->set_unit_name(unit_name_);
41721   if (unit_multiplier_ != 1)
41722     counter->set_unit_multiplier(unit_multiplier_);
41723   if (is_incremental_)
41724     counter->set_is_incremental(is_incremental_);
41725   return desc;
41726 }
41727 
Serialize(protos::pbzero::TrackDescriptor * desc) const41728 void CounterTrack::Serialize(protos::pbzero::TrackDescriptor* desc) const {
41729   auto bytes = Serialize().SerializeAsString();
41730   desc->AppendRawProtoBytes(bytes.data(), bytes.size());
41731 }
41732 
41733 namespace internal {
41734 namespace {
41735 
GetProcessStartTime()41736 uint64_t GetProcessStartTime() {
41737 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
41738   std::string stat;
41739   if (!base::ReadFile("/proc/self/stat", &stat))
41740     return 0u;
41741   // The stat file is a single line split into space-separated fields as "pid
41742   // (comm) state ppid ...". However because the command name can contain any
41743   // characters (including parentheses and spaces), we need to skip past it
41744   // before parsing the rest of the fields. To do that, we look for the last
41745   // instance of ") " (parentheses followed by space) and parse forward from
41746   // that point.
41747   size_t comm_end = stat.rfind(") ");
41748   if (comm_end == std::string::npos)
41749     return 0u;
41750   stat = stat.substr(comm_end + strlen(") "));
41751   base::StringSplitter splitter(stat, ' ');
41752   for (size_t skip = 0; skip < 20; skip++) {
41753     if (!splitter.Next())
41754       return 0u;
41755   }
41756   return base::CStringToUInt64(splitter.cur_token()).value_or(0u);
41757 #else
41758   return 0;
41759 #endif  // !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
41760 }
41761 
41762 }  // namespace
41763 
41764 // static
41765 TrackRegistry* TrackRegistry::instance_;
41766 
41767 TrackRegistry::TrackRegistry() = default;
41768 TrackRegistry::~TrackRegistry() = default;
41769 
41770 // static
InitializeInstance()41771 void TrackRegistry::InitializeInstance() {
41772   // TODO(eseckler): Chrome may call this more than once. Once Chrome doesn't
41773   // call this directly anymore, bring back DCHECK(!instance_) instead.
41774   if (instance_)
41775     return;
41776   instance_ = new TrackRegistry();
41777 
41778   // Use the process start time + pid as the unique identifier for this process.
41779   // This ensures that if there are two independent copies of the Perfetto SDK
41780   // in the same process (e.g., one in the app and another in a system
41781   // framework), events emitted by each will be consistently interleaved on
41782   // common thread and process tracks.
41783   if (uint64_t start_time = GetProcessStartTime()) {
41784     base::Hash hash;
41785     hash.Update(start_time);
41786     hash.Update(base::GetProcessId());
41787     Track::process_uuid = hash.digest();
41788   } else {
41789     // Fall back to a randomly generated identifier.
41790     Track::process_uuid = static_cast<uint64_t>(base::Uuidv4().lsb());
41791   }
41792 }
41793 
UpdateTrack(Track track,const std::string & serialized_desc)41794 void TrackRegistry::UpdateTrack(Track track,
41795                                 const std::string& serialized_desc) {
41796   std::lock_guard<std::mutex> lock(mutex_);
41797   tracks_[track.uuid] = std::move(serialized_desc);
41798 }
41799 
UpdateTrackImpl(Track track,std::function<void (protos::pbzero::TrackDescriptor *)> fill_function)41800 void TrackRegistry::UpdateTrackImpl(
41801     Track track,
41802     std::function<void(protos::pbzero::TrackDescriptor*)> fill_function) {
41803   constexpr size_t kInitialSliceSize = 32;
41804   constexpr size_t kMaximumSliceSize = 4096;
41805   protozero::HeapBuffered<protos::pbzero::TrackDescriptor> new_descriptor(
41806       kInitialSliceSize, kMaximumSliceSize);
41807   fill_function(new_descriptor.get());
41808   auto serialized_desc = new_descriptor.SerializeAsString();
41809   UpdateTrack(track, serialized_desc);
41810 }
41811 
EraseTrack(Track track)41812 void TrackRegistry::EraseTrack(Track track) {
41813   std::lock_guard<std::mutex> lock(mutex_);
41814   tracks_.erase(track.uuid);
41815 }
41816 
41817 // static
WriteTrackDescriptor(const SerializedTrackDescriptor & desc,protozero::MessageHandle<protos::pbzero::TracePacket> packet)41818 void TrackRegistry::WriteTrackDescriptor(
41819     const SerializedTrackDescriptor& desc,
41820     protozero::MessageHandle<protos::pbzero::TracePacket> packet) {
41821   packet->AppendString(
41822       perfetto::protos::pbzero::TracePacket::kTrackDescriptorFieldNumber, desc);
41823 }
41824 
41825 }  // namespace internal
41826 }  // namespace perfetto
41827 // gen_amalgamated begin source: src/tracing/track_event_category_registry.cc
41828 /*
41829  * Copyright (C) 2019 The Android Open Source Project
41830  *
41831  * Licensed under the Apache License, Version 2.0 (the "License");
41832  * you may not use this file except in compliance with the License.
41833  * You may obtain a copy of the License at
41834  *
41835  *      http://www.apache.org/licenses/LICENSE-2.0
41836  *
41837  * Unless required by applicable law or agreed to in writing, software
41838  * distributed under the License is distributed on an "AS IS" BASIS,
41839  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
41840  * See the License for the specific language governing permissions and
41841  * limitations under the License.
41842  */
41843 
41844 // gen_amalgamated expanded: #include "perfetto/tracing/track_event_category_registry.h"
41845 
41846 namespace perfetto {
41847 
41848 // static
FromDynamicCategory(const char * name)41849 Category Category::FromDynamicCategory(const char* name) {
41850   if (GetNthNameSize(1, name, name)) {
41851     Category group(Group(name));
41852     PERFETTO_DCHECK(group.name);
41853     return group;
41854   }
41855   Category category(name);
41856   PERFETTO_DCHECK(category.name);
41857   return category;
41858 }
41859 
FromDynamicCategory(const DynamicCategory & dynamic_category)41860 Category Category::FromDynamicCategory(
41861     const DynamicCategory& dynamic_category) {
41862   return FromDynamicCategory(dynamic_category.name.c_str());
41863 }
41864 
41865 namespace internal {
41866 
NullCategory(const perfetto::DynamicCategory &)41867 perfetto::DynamicCategory NullCategory(const perfetto::DynamicCategory&) {
41868   return perfetto::DynamicCategory{};
41869 }
41870 
EnableCategoryForInstance(size_t category_index,uint32_t instance_index) const41871 void TrackEventCategoryRegistry::EnableCategoryForInstance(
41872     size_t category_index,
41873     uint32_t instance_index) const {
41874   PERFETTO_DCHECK(instance_index < kMaxDataSourceInstances);
41875   PERFETTO_DCHECK(category_index < category_count_);
41876   // Matches the acquire_load in DataSource::Trace().
41877   state_storage_[category_index].fetch_or(
41878       static_cast<uint8_t>(1u << instance_index), std::memory_order_release);
41879 }
41880 
DisableCategoryForInstance(size_t category_index,uint32_t instance_index) const41881 void TrackEventCategoryRegistry::DisableCategoryForInstance(
41882     size_t category_index,
41883     uint32_t instance_index) const {
41884   PERFETTO_DCHECK(instance_index < kMaxDataSourceInstances);
41885   PERFETTO_DCHECK(category_index < category_count_);
41886   // Matches the acquire_load in DataSource::Trace().
41887   state_storage_[category_index].fetch_and(
41888       static_cast<uint8_t>(~(1u << instance_index)), std::memory_order_release);
41889 }
41890 
41891 }  // namespace internal
41892 }  // namespace perfetto
41893 // gen_amalgamated begin source: src/tracing/track_event_legacy.cc
41894 /*
41895  * Copyright (C) 2020 The Android Open Source Project
41896  *
41897  * Licensed under the Apache License, Version 2.0 (the "License");
41898  * you may not use this file except in compliance with the License.
41899  * You may obtain a copy of the License at
41900  *
41901  *      http://www.apache.org/licenses/LICENSE-2.0
41902  *
41903  * Unless required by applicable law or agreed to in writing, software
41904  * distributed under the License is distributed on an "AS IS" BASIS,
41905  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
41906  * See the License for the specific language governing permissions and
41907  * limitations under the License.
41908  */
41909 
41910 // gen_amalgamated expanded: #include "perfetto/tracing/track_event_legacy.h"
41911 
41912 // gen_amalgamated expanded: #include "perfetto/tracing/track.h"
41913 
41914 namespace perfetto {
41915 namespace legacy {
41916 
41917 template <>
ConvertThreadId(const PerfettoLegacyCurrentThreadId &)41918 ThreadTrack ConvertThreadId(const PerfettoLegacyCurrentThreadId&) {
41919   // Because of the short-circuit in PERFETTO_INTERNAL_LEGACY_EVENT, we should
41920   // never get here.
41921   PERFETTO_DCHECK(false);
41922   return ThreadTrack::Current();
41923 }
41924 
41925 }  // namespace legacy
41926 
41927 namespace internal {
41928 
Write(protos::pbzero::TrackEvent::LegacyEvent * event,uint32_t event_flags) const41929 void LegacyTraceId::Write(protos::pbzero::TrackEvent::LegacyEvent* event,
41930                           uint32_t event_flags) const {
41931   // Legacy flow events always use bind_id.
41932   if (event_flags &
41933       (legacy::kTraceEventFlagFlowOut | legacy::kTraceEventFlagFlowIn)) {
41934     // Flow bind_ids don't have scopes, so we need to mangle in-process ones to
41935     // avoid collisions.
41936     if (id_flags_ & legacy::kTraceEventFlagHasLocalId) {
41937       event->set_bind_id(raw_id_ ^ ProcessTrack::Current().uuid);
41938     } else {
41939       event->set_bind_id(raw_id_);
41940     }
41941     return;
41942   }
41943 
41944   uint32_t scope_flags = id_flags_ & (legacy::kTraceEventFlagHasId |
41945                                       legacy::kTraceEventFlagHasLocalId |
41946                                       legacy::kTraceEventFlagHasGlobalId);
41947   switch (scope_flags) {
41948     case legacy::kTraceEventFlagHasId:
41949       event->set_unscoped_id(raw_id_);
41950       break;
41951     case legacy::kTraceEventFlagHasLocalId:
41952       event->set_local_id(raw_id_);
41953       break;
41954     case legacy::kTraceEventFlagHasGlobalId:
41955       event->set_global_id(raw_id_);
41956       break;
41957   }
41958   if (scope_)
41959     event->set_id_scope(scope_);
41960 }
41961 
41962 }  // namespace internal
41963 }  // namespace perfetto
41964 // gen_amalgamated begin source: src/tracing/track_event_state_tracker.cc
41965 /*
41966  * Copyright (C) 2020 The Android Open Source Project
41967  *
41968  * Licensed under the Apache License, Version 2.0 (the "License");
41969  * you may not use this file except in compliance with the License.
41970  * You may obtain a copy of the License at
41971  *
41972  *      http://www.apache.org/licenses/LICENSE-2.0
41973  *
41974  * Unless required by applicable law or agreed to in writing, software
41975  * distributed under the License is distributed on an "AS IS" BASIS,
41976  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
41977  * See the License for the specific language governing permissions and
41978  * limitations under the License.
41979  */
41980 
41981 // gen_amalgamated expanded: #include "perfetto/tracing/track_event_state_tracker.h"
41982 
41983 // gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
41984 
41985 // gen_amalgamated expanded: #include "protos/perfetto/common/interceptor_descriptor.gen.h"
41986 // gen_amalgamated expanded: #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
41987 // gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
41988 // gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet_defaults.pbzero.h"
41989 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
41990 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/process_descriptor.pbzero.h"
41991 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/thread_descriptor.pbzero.h"
41992 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_descriptor.pbzero.h"
41993 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.pbzero.h"
41994 
41995 namespace perfetto {
41996 
41997 TrackEventStateTracker::~TrackEventStateTracker() = default;
41998 TrackEventStateTracker::Delegate::~Delegate() = default;
41999 
42000 // static
ProcessTracePacket(Delegate & delegate,SequenceState & sequence_state,const protos::pbzero::TracePacket_Decoder & packet)42001 void TrackEventStateTracker::ProcessTracePacket(
42002     Delegate& delegate,
42003     SequenceState& sequence_state,
42004     const protos::pbzero::TracePacket_Decoder& packet) {
42005   UpdateIncrementalState(delegate, sequence_state, packet);
42006 
42007   if (!packet.has_track_event())
42008     return;
42009   perfetto::protos::pbzero::TrackEvent::Decoder track_event(
42010       packet.track_event());
42011 
42012   // TODO(skyostil): Support incremental timestamps.
42013   uint64_t timestamp = packet.timestamp();
42014 
42015   Track* track = &sequence_state.track;
42016   if (track_event.has_track_uuid()) {
42017     auto* session_state = delegate.GetSessionState();
42018     if (!session_state)
42019       return;  // Tracing must have ended.
42020     track = &session_state->tracks[track_event.track_uuid()];
42021   }
42022 
42023   // We only log the first category of each event.
42024   protozero::ConstChars category{};
42025   uint64_t category_iid = 0;
42026   if (auto iid_it = track_event.category_iids()) {
42027     category_iid = *iid_it;
42028     category.data = sequence_state.event_categories[category_iid].data();
42029     category.size = sequence_state.event_categories[category_iid].size();
42030   } else if (auto cat_it = track_event.categories()) {
42031     category.data = reinterpret_cast<const char*>(cat_it->data());
42032     category.size = cat_it->size();
42033   }
42034 
42035   protozero::ConstChars name{};
42036   uint64_t name_iid = track_event.name_iid();
42037   uint64_t name_hash = 0;
42038   uint64_t duration = 0;
42039   if (name_iid) {
42040     name.data = sequence_state.event_names[name_iid].data();
42041     name.size = sequence_state.event_names[name_iid].size();
42042   } else if (track_event.has_name()) {
42043     name.data = track_event.name().data;
42044     name.size = track_event.name().size;
42045   }
42046 
42047   if (name.data) {
42048     base::Hash hash;
42049     hash.Update(name.data, name.size);
42050     name_hash = hash.digest();
42051   }
42052 
42053   size_t depth = track->stack.size();
42054   switch (track_event.type()) {
42055     case protos::pbzero::TrackEvent::TYPE_SLICE_BEGIN: {
42056       StackFrame frame;
42057       frame.timestamp = timestamp;
42058       frame.name_hash = name_hash;
42059       if (track_event.has_track_uuid()) {
42060         frame.name = name.ToStdString();
42061         frame.category = category.ToStdString();
42062       } else {
42063         frame.name_iid = name_iid;
42064         frame.category_iid = category_iid;
42065       }
42066       track->stack.push_back(std::move(frame));
42067       break;
42068     }
42069     case protos::pbzero::TrackEvent::TYPE_SLICE_END:
42070       if (!track->stack.empty()) {
42071         const auto& prev_frame = track->stack.back();
42072         if (prev_frame.name_iid) {
42073           name.data = sequence_state.event_names[prev_frame.name_iid].data();
42074           name.size = sequence_state.event_names[prev_frame.name_iid].size();
42075         } else {
42076           name.data = prev_frame.name.data();
42077           name.size = prev_frame.name.size();
42078         }
42079         name_hash = prev_frame.name_hash;
42080         if (prev_frame.category_iid) {
42081           category.data =
42082               sequence_state.event_categories[prev_frame.category_iid].data();
42083           category.size =
42084               sequence_state.event_categories[prev_frame.category_iid].size();
42085         } else {
42086           category.data = prev_frame.category.data();
42087           category.size = prev_frame.category.size();
42088         }
42089         duration = timestamp - prev_frame.timestamp;
42090         depth--;
42091       }
42092       break;
42093     case protos::pbzero::TrackEvent::TYPE_INSTANT:
42094       break;
42095     case protos::pbzero::TrackEvent::TYPE_COUNTER:
42096     case protos::pbzero::TrackEvent::TYPE_UNSPECIFIED:
42097       // TODO(skyostil): Support counters.
42098       return;
42099   }
42100 
42101   ParsedTrackEvent parsed_event{track_event};
42102   parsed_event.timestamp_ns = timestamp;
42103   parsed_event.duration_ns = duration;
42104   parsed_event.stack_depth = depth;
42105   parsed_event.category = category;
42106   parsed_event.name = name;
42107   parsed_event.name_hash = name_hash;
42108   delegate.OnTrackEvent(*track, parsed_event);
42109 
42110   if (track_event.type() == protos::pbzero::TrackEvent::TYPE_SLICE_END &&
42111       !track->stack.empty()) {
42112     track->stack.pop_back();
42113   }
42114 }
42115 
42116 // static
UpdateIncrementalState(Delegate & delegate,SequenceState & sequence_state,const protos::pbzero::TracePacket_Decoder & packet)42117 void TrackEventStateTracker::UpdateIncrementalState(
42118     Delegate& delegate,
42119     SequenceState& sequence_state,
42120     const protos::pbzero::TracePacket_Decoder& packet) {
42121 #if PERFETTO_DCHECK_IS_ON()
42122   if (!sequence_state.sequence_id) {
42123     sequence_state.sequence_id = packet.trusted_packet_sequence_id();
42124   } else {
42125     PERFETTO_DCHECK(sequence_state.sequence_id ==
42126                     packet.trusted_packet_sequence_id());
42127   }
42128 #endif
42129 
42130   if (packet.sequence_flags() &
42131       perfetto::protos::pbzero::TracePacket::SEQ_INCREMENTAL_STATE_CLEARED) {
42132     // Convert any existing event names and categories on the stack to
42133     // non-interned strings so we can look up their names even after the
42134     // incremental state is gone.
42135     for (auto& frame : sequence_state.track.stack) {
42136       if (frame.name_iid) {
42137         frame.name = sequence_state.event_names[frame.name_iid];
42138         frame.name_iid = 0u;
42139       }
42140       if (frame.category_iid) {
42141         frame.category = sequence_state.event_categories[frame.category_iid];
42142         frame.category_iid = 0u;
42143       }
42144     }
42145     sequence_state.event_names.clear();
42146     sequence_state.event_categories.clear();
42147     sequence_state.debug_annotation_names.clear();
42148     sequence_state.track.uuid = 0u;
42149     sequence_state.track.index = 0u;
42150   }
42151   if (packet.has_interned_data()) {
42152     perfetto::protos::pbzero::InternedData::Decoder interned_data(
42153         packet.interned_data());
42154     for (auto it = interned_data.event_names(); it; it++) {
42155       perfetto::protos::pbzero::EventName::Decoder entry(*it);
42156       sequence_state.event_names[entry.iid()] = entry.name().ToStdString();
42157     }
42158     for (auto it = interned_data.event_categories(); it; it++) {
42159       perfetto::protos::pbzero::EventCategory::Decoder entry(*it);
42160       sequence_state.event_categories[entry.iid()] = entry.name().ToStdString();
42161     }
42162     for (auto it = interned_data.debug_annotation_names(); it; it++) {
42163       perfetto::protos::pbzero::DebugAnnotationName::Decoder entry(*it);
42164       sequence_state.debug_annotation_names[entry.iid()] =
42165           entry.name().ToStdString();
42166     }
42167   }
42168   if (packet.has_trace_packet_defaults()) {
42169     perfetto::protos::pbzero::TracePacketDefaults::Decoder defaults(
42170         packet.trace_packet_defaults());
42171     if (defaults.has_track_event_defaults()) {
42172       perfetto::protos::pbzero::TrackEventDefaults::Decoder
42173           track_event_defaults(defaults.track_event_defaults());
42174       sequence_state.track.uuid = track_event_defaults.track_uuid();
42175     }
42176   }
42177   if (packet.has_track_descriptor()) {
42178     perfetto::protos::pbzero::TrackDescriptor::Decoder track_descriptor(
42179         packet.track_descriptor());
42180     auto* session_state = delegate.GetSessionState();
42181     auto& track = session_state->tracks[track_descriptor.uuid()];
42182     if (!track.index)
42183       track.index = static_cast<uint32_t>(session_state->tracks.size() + 1);
42184     track.uuid = track_descriptor.uuid();
42185 
42186     track.name = track_descriptor.name().ToStdString();
42187     track.pid = 0;
42188     track.tid = 0;
42189     if (track_descriptor.has_process()) {
42190       perfetto::protos::pbzero::ProcessDescriptor::Decoder process(
42191           track_descriptor.process());
42192       track.pid = process.pid();
42193       if (track.name.empty())
42194         track.name = process.process_name().ToStdString();
42195     } else if (track_descriptor.has_thread()) {
42196       perfetto::protos::pbzero::ThreadDescriptor::Decoder thread(
42197           track_descriptor.thread());
42198       track.pid = thread.pid();
42199       track.tid = thread.tid();
42200       if (track.name.empty())
42201         track.name = thread.thread_name().ToStdString();
42202     }
42203     delegate.OnTrackUpdated(track);
42204 
42205     // Mirror properties to the default track of the sequence. Note that
42206     // this does not catch updates to the default track written through other
42207     // sequences.
42208     if (track.uuid == sequence_state.track.uuid) {
42209       sequence_state.track.index = track.index;
42210       sequence_state.track.name = track.name;
42211       sequence_state.track.pid = track.pid;
42212       sequence_state.track.tid = track.tid;
42213       sequence_state.track.user_data = track.user_data;
42214     }
42215   }
42216 }
42217 
ParsedTrackEvent(const perfetto::protos::pbzero::TrackEvent::Decoder & track_event_)42218 TrackEventStateTracker::ParsedTrackEvent::ParsedTrackEvent(
42219     const perfetto::protos::pbzero::TrackEvent::Decoder& track_event_)
42220     : track_event(track_event_) {}
42221 
42222 }  // namespace perfetto
42223 // gen_amalgamated begin source: src/tracing/virtual_destructors.cc
42224 /*
42225  * Copyright (C) 2019 The Android Open Source Project
42226  *
42227  * Licensed under the Apache License, Version 2.0 (the "License");
42228  * you may not use this file except in compliance with the License.
42229  * You may obtain a copy of the License at
42230  *
42231  *      http://www.apache.org/licenses/LICENSE-2.0
42232  *
42233  * Unless required by applicable law or agreed to in writing, software
42234  * distributed under the License is distributed on an "AS IS" BASIS,
42235  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
42236  * See the License for the specific language governing permissions and
42237  * limitations under the License.
42238  */
42239 
42240 // gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_tls.h"
42241 // gen_amalgamated expanded: #include "perfetto/tracing/tracing.h"
42242 // gen_amalgamated expanded: #include "perfetto/tracing/tracing_backend.h"
42243 
42244 // This translation unit contains the definitions for the destructor of pure
42245 // virtual interfaces for the src/public:public target. The alternative would be
42246 // introducing a one-liner .cc file for each pure virtual interface, which is
42247 // overkill. This is for compliance with -Wweak-vtables.
42248 
42249 namespace perfetto {
42250 namespace internal {
42251 
~TracingTLS()42252 TracingTLS::~TracingTLS() {
42253   // Avoid entering trace points while the thread is being torn down.
42254   is_in_trace_point = true;
42255 }
42256 
42257 }  // namespace internal
42258 
42259 TracingBackend::~TracingBackend() = default;
42260 TracingSession::~TracingSession() = default;
42261 
42262 }  // namespace perfetto
42263 // gen_amalgamated begin source: src/android_stats/statsd_logging_helper.cc
42264 // gen_amalgamated begin header: src/android_stats/statsd_logging_helper.h
42265 // gen_amalgamated begin header: src/android_stats/perfetto_atoms.h
42266 /*
42267  * Copyright (C) 2020 The Android Open Source Project
42268  *
42269  * Licensed under the Apache License, Version 2.0 (the "License");
42270  * you may not use this file except in compliance with the License.
42271  * You may obtain a copy of the License at
42272  *
42273  *      http://www.apache.org/licenses/LICENSE-2.0
42274  *
42275  * Unless required by applicable law or agreed to in writing, software
42276  * distributed under the License is distributed on an "AS IS" BASIS,
42277  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
42278  * See the License for the specific language governing permissions and
42279  * limitations under the License.
42280  */
42281 
42282 #ifndef SRC_ANDROID_STATS_PERFETTO_ATOMS_H_
42283 #define SRC_ANDROID_STATS_PERFETTO_ATOMS_H_
42284 
42285 namespace perfetto {
42286 
42287 // This must match the values of the PerfettoUploadEvent enum in:
42288 // frameworks/proto_logging/stats/atoms.proto
42289 enum class PerfettoStatsdAtom {
42290   kUndefined = 0,
42291 
42292   // Checkpoints inside perfetto_cmd before tracing is finished.
42293   kTraceBegin = 1,
42294   kBackgroundTraceBegin = 2,
42295   kOnConnect = 3,
42296 
42297   // Guardrails inside perfetto_cmd before tracing is finished.
42298   kOnTimeout = 16,
42299   kCmdUserBuildTracingNotAllowed = 43,
42300   kCmdFailedToInitGuardrailState = 44,
42301   kCmdInvalidGuardrailState = 45,
42302   kCmdHitUploadLimit = 46,
42303 
42304   // Checkpoints inside traced.
42305   kTracedEnableTracing = 37,
42306   kTracedStartTracing = 38,
42307   kTracedDisableTracing = 39,
42308   kTracedNotifyTracingDisabled = 40,
42309 
42310   // Trigger checkpoints inside traced.
42311   // These atoms are special because, along with the UUID,
42312   // they log the trigger name.
42313   kTracedTriggerStartTracing = 41,
42314   kTracedTriggerStopTracing = 42,
42315 
42316   // Guardrails inside traced.
42317   kTracedEnableTracingExistingTraceSession = 18,
42318   kTracedEnableTracingTooLongTrace = 19,
42319   kTracedEnableTracingInvalidTriggerTimeout = 20,
42320   kTracedEnableTracingDurationWithTrigger = 21,
42321   kTracedEnableTracingStopTracingWriteIntoFile = 22,
42322   kTracedEnableTracingDuplicateTriggerName = 23,
42323   kTracedEnableTracingInvalidDeferredStart = 24,
42324   kTracedEnableTracingInvalidBufferSize = 25,
42325   kTracedEnableTracingBufferSizeTooLarge = 26,
42326   kTracedEnableTracingTooManyBuffers = 27,
42327   kTracedEnableTracingDuplicateSessionName = 28,
42328   kTracedEnableTracingSessionNameTooRecent = 29,
42329   kTracedEnableTracingTooManySessionsForUid = 30,
42330   kTracedEnableTracingTooManyConcurrentSessions = 31,
42331   kTracedEnableTracingInvalidFdOutputFile = 32,
42332   kTracedEnableTracingFailedToCreateFile = 33,
42333   kTracedEnableTracingOom = 34,
42334   kTracedEnableTracingUnknown = 35,
42335   kTracedStartTracingInvalidSessionState = 36,
42336   kTracedEnableTracingInvalidFilter = 47,
42337 
42338   // Checkpoints inside perfetto_cmd after tracing has finished.
42339   kOnTracingDisabled = 4,
42340   kUploadIncidentBegin = 8,
42341   kFinalizeTraceAndExit = 11,
42342   kNotUploadingEmptyTrace = 17,
42343 
42344   // Guardrails inside perfetto_cmd after tracing has finished.
42345   kUploadIncidentFailure = 10,
42346 
42347   // Deprecated as "success" is misleading; it simply means we were
42348   // able to communicate with incidentd. Will be removed once
42349   // incidentd is properly instrumented.
42350   kUploadIncidentSuccess = 9,
42351 
42352   // Deprecated as has the potential to be too spammy. Will be
42353   // replaced with a whole new atom proto which uses a count metric
42354   // instead of the event metric used for this proto.
42355   kTriggerBegin = 12,
42356   kTriggerSuccess = 13,
42357   kTriggerFailure = 14,
42358 
42359   // Deprecated as too coarse grained to be useful. Will be replaced
42360   // with better broken down atoms as we do with traced.
42361   kHitGuardrails = 15,
42362 
42363   // Contained status of Dropbox uploads. Removed as Perfetto no
42364   // longer supports uploading traces using Dropbox.
42365   // reserved 5, 6, 7;
42366 };
42367 
42368 // This must match the values of the PerfettoTrigger::TriggerType enum in:
42369 // frameworks/base/cmds/statsd/src/atoms.proto
42370 enum PerfettoTriggerAtom {
42371   kUndefined = 0,
42372 
42373   kCmdTrigger = 1,
42374   kCmdTriggerFail = 2,
42375 
42376   kTriggerPerfettoTrigger = 3,
42377   kTriggerPerfettoTriggerFail = 4,
42378 
42379   kTracedLimitProbability = 5,
42380   kTracedLimitMaxPer24h = 6,
42381 
42382   kProbesProducerTrigger = 7,
42383   kProbesProducerTriggerFail = 8,
42384 };
42385 
42386 }  // namespace perfetto
42387 
42388 #endif  // SRC_ANDROID_STATS_PERFETTO_ATOMS_H_
42389 /*
42390  * Copyright (C) 2020 The Android Open Source Project
42391  *
42392  * Licensed under the Apache License, Version 2.0 (the "License");
42393  * you may not use this file except in compliance with the License.
42394  * You may obtain a copy of the License at
42395  *
42396  *      http://www.apache.org/licenses/LICENSE-2.0
42397  *
42398  * Unless required by applicable law or agreed to in writing, software
42399  * distributed under the License is distributed on an "AS IS" BASIS,
42400  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
42401  * See the License for the specific language governing permissions and
42402  * limitations under the License.
42403  */
42404 
42405 #ifndef SRC_ANDROID_STATS_STATSD_LOGGING_HELPER_H_
42406 #define SRC_ANDROID_STATS_STATSD_LOGGING_HELPER_H_
42407 
42408 #include <stdint.h>
42409 #include <string>
42410 #include <vector>
42411 
42412 // gen_amalgamated expanded: #include "src/android_stats/perfetto_atoms.h"
42413 
42414 namespace perfetto {
42415 namespace android_stats {
42416 
42417 // Functions in this file are only active on built in the Android
42418 // tree. On other platforms (including Android standalone and Chromium
42419 // on Android) these functions are a noop.
42420 
42421 // Logs the upload event to statsd if built in the Android tree.
42422 void MaybeLogUploadEvent(PerfettoStatsdAtom atom,
42423                          int64_t uuid_lsb,
42424                          int64_t uuid_msb,
42425                          const std::string& trigger_name = "");
42426 
42427 // Logs the trigger events to statsd if built in the Android tree.
42428 void MaybeLogTriggerEvent(PerfettoTriggerAtom atom, const std::string& trigger);
42429 
42430 // Logs the trigger events to statsd if built in the Android tree.
42431 void MaybeLogTriggerEvents(PerfettoTriggerAtom atom,
42432                            const std::vector<std::string>& triggers);
42433 
42434 }  // namespace android_stats
42435 }  // namespace perfetto
42436 
42437 #endif  // SRC_ANDROID_STATS_STATSD_LOGGING_HELPER_H_
42438 /*
42439  * Copyright (C) 2020 The Android Open Source Project
42440  *
42441  * Licensed under the Apache License, Version 2.0 (the "License");
42442  * you may not use this file except in compliance with the License.
42443  * You may obtain a copy of the License at
42444  *
42445  *      http://www.apache.org/licenses/LICENSE-2.0
42446  *
42447  * Unless required by applicable law or agreed to in writing, software
42448  * distributed under the License is distributed on an "AS IS" BASIS,
42449  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
42450  * See the License for the specific language governing permissions and
42451  * limitations under the License.
42452  */
42453 
42454 // gen_amalgamated expanded: #include "src/android_stats/statsd_logging_helper.h"
42455 
42456 #include <string>
42457 
42458 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
42459 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
42460 
42461 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
42462     PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
42463 // gen_amalgamated expanded: #include "src/android_internal/lazy_library_loader.h"  // nogncheck
42464 // gen_amalgamated expanded: #include "src/android_internal/statsd_logging.h"       // nogncheck
42465 #endif
42466 
42467 namespace perfetto {
42468 namespace android_stats {
42469 
42470 // Make sure we don't accidentally log on non-Android tree build. Note that even
42471 // removing this ifdef still doesn't make uploads work on OS_ANDROID.
42472 // PERFETTO_LAZY_LOAD will return a nullptr on non-Android and non-in-tree
42473 // builds as libperfetto_android_internal will not be available.
42474 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
42475     PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
42476 
MaybeLogUploadEvent(PerfettoStatsdAtom atom,int64_t uuid_lsb,int64_t uuid_msb,const std::string & trigger_name)42477 void MaybeLogUploadEvent(PerfettoStatsdAtom atom,
42478                          int64_t uuid_lsb,
42479                          int64_t uuid_msb,
42480                          const std::string& trigger_name) {
42481   PERFETTO_LAZY_LOAD(android_internal::StatsdLogUploadEvent, log_event_fn);
42482   if (log_event_fn) {
42483     log_event_fn(atom, uuid_lsb, uuid_msb, trigger_name.c_str());
42484   }
42485 }
42486 
MaybeLogTriggerEvent(PerfettoTriggerAtom atom,const std::string & trigger_name)42487 void MaybeLogTriggerEvent(PerfettoTriggerAtom atom,
42488                           const std::string& trigger_name) {
42489   PERFETTO_LAZY_LOAD(android_internal::StatsdLogTriggerEvent, log_event_fn);
42490   if (log_event_fn) {
42491     log_event_fn(atom, trigger_name.c_str());
42492   }
42493 }
42494 
MaybeLogTriggerEvents(PerfettoTriggerAtom atom,const std::vector<std::string> & triggers)42495 void MaybeLogTriggerEvents(PerfettoTriggerAtom atom,
42496                            const std::vector<std::string>& triggers) {
42497   PERFETTO_LAZY_LOAD(android_internal::StatsdLogTriggerEvent, log_event_fn);
42498   if (log_event_fn) {
42499     for (const std::string& trigger_name : triggers) {
42500       log_event_fn(atom, trigger_name.c_str());
42501     }
42502   }
42503 }
42504 
42505 #else
42506 void MaybeLogUploadEvent(PerfettoStatsdAtom,
42507                          int64_t,
42508                          int64_t,
42509                          const std::string&) {}
42510 void MaybeLogTriggerEvent(PerfettoTriggerAtom, const std::string&) {}
42511 void MaybeLogTriggerEvents(PerfettoTriggerAtom,
42512                            const std::vector<std::string>&) {}
42513 #endif
42514 
42515 }  // namespace android_stats
42516 }  // namespace perfetto
42517 // gen_amalgamated begin source: src/protozero/filtering/filter_bytecode_parser.cc
42518 // gen_amalgamated begin header: src/protozero/filtering/filter_bytecode_parser.h
42519 /*
42520  * Copyright (C) 2021 The Android Open Source Project
42521  *
42522  * Licensed under the Apache License, Version 2.0 (the "License");
42523  * you may not use this file except in compliance with the License.
42524  * You may obtain a copy of the License at
42525  *
42526  *      http://www.apache.org/licenses/LICENSE-2.0
42527  *
42528  * Unless required by applicable law or agreed to in writing, software
42529  * distributed under the License is distributed on an "AS IS" BASIS,
42530  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
42531  * See the License for the specific language governing permissions and
42532  * limitations under the License.
42533  */
42534 
42535 #ifndef SRC_PROTOZERO_FILTERING_FILTER_BYTECODE_PARSER_H_
42536 #define SRC_PROTOZERO_FILTERING_FILTER_BYTECODE_PARSER_H_
42537 
42538 #include <stddef.h>
42539 #include <stdint.h>
42540 
42541 #include <vector>
42542 
42543 namespace protozero {
42544 
42545 // Loads the proto-encoded bytecode in memory and allows fast lookups for tuples
42546 // (msg_index, field_id) to tell if a given field should be allowed or not and,
42547 // in the case of nested fields, what is the next message index to recurse into.
42548 // This class does two things:
42549 // 1. Expands the array of varint from the proto into a vector<uint32_t>. This
42550 //    is to avoid performing varint decoding on every lookup, at the cost of
42551 //    some extra memory (2KB-4KB). Note that the expanded vector is not just a
42552 //    1:1 copy of the proto one (more below). This is to avoid O(Fields) linear
42553 //    lookup complexity.
42554 // 2. Creates an index of offsets to remember the start word for each message.
42555 //    This is so we can jump to O(1) to the N-th message when recursing into a
42556 //    nested fields, without having to scan and find the (N-1)-th END_OF_MESSAGE
42557 //    marker.
42558 // Overall lookups are O(1) for field ids < 128 (kDirectlyIndexLimit) and O(N),
42559 // with N being the number of allowed field ranges for other fields.
42560 // See comments around |word_| below for the structure of the word vector.
42561 class FilterBytecodeParser {
42562  public:
42563   // Result of a Query() operation
42564   struct QueryResult {
42565     bool allowed;  // Whether the field is allowed at all or no.
42566 
42567     // If |allowed|==true && simple_field()==false, this tells the message index
42568     // of the nested field that should be used when recursing in the parser.
42569     uint32_t nested_msg_index;
42570 
42571     // If |allowed|==true, specifies if the field is of a simple type (varint,
42572     // fixed32/64, string or byte) or a nested field that needs recursion.
42573     // In the latter case the caller is expected to use |nested_msg_index| for
42574     // the next Query() calls.
simple_fieldprotozero::FilterBytecodeParser::QueryResult42575     bool simple_field() const { return nested_msg_index == kSimpleField; }
42576   };
42577 
42578   // Loads a filter. The filter data consists of a sequence of varints which
42579   // contains the filter opcodes and a final checksum.
42580   bool Load(const void* filter_data, size_t len);
42581 
42582   // Checks wheter a given field is allowed or not.
42583   // msg_index = 0 is the index of the root message, where all queries should
42584   // start from (typically perfetto.protos.Trace).
42585   QueryResult Query(uint32_t msg_index, uint32_t field_id);
42586 
42587   void Reset();
set_suppress_logs_for_fuzzer(bool x)42588   void set_suppress_logs_for_fuzzer(bool x) { suppress_logs_for_fuzzer_ = x; }
42589 
42590  private:
42591   static constexpr uint32_t kDirectlyIndexLimit = 128;
42592   static constexpr uint32_t kAllowed = 1u << 31u;
42593   static constexpr uint32_t kSimpleField = 0x7fffffff;
42594 
42595   bool LoadInternal(const uint8_t* filter_data, size_t len);
42596 
42597   // The state of all fields for all messages is stored in one contiguous array.
42598   // This is to avoid memory fragmentation and allocator overhead.
42599   // We expect a high number of messages (hundreds), but each message is small.
42600   // For each message we store two sets of uint32:
42601   // 1. A set of "directly indexed" fields, for field ids < 128.
42602   // 2. The remainder is a set of ranges.
42603   // So each message descriptor consists of a sequence of words as follows:
42604   //
42605   // [0] -> how many directly indexed fields are stored next (up to 128)
42606   //
42607   // [1..N] -> One word per field id (See "field state" below).
42608   //
42609   // [N + 1] -> Start of field id range 1
42610   // [N + 2] -> End of field id range 1 (exclusive, STL-style).
42611   // [N + 3] -> Field state for fields in range 1 (below)
42612   //
42613   // [N + 4] -> Start of field id range 2
42614   // [N + 5] -> End of field id range 2 (exclusive, STL-style).
42615   // [N + 6] -> Field state for fields in range 2 (below)
42616 
42617   // The "field state" word is as follows:
42618   // Bit 31: 0 if the field is disallowed, 1 if allowed.
42619   //         Only directly indexed fields can be 0 (it doesn't make sense to add
42620   //         a range and then say "btw it's NOT allowed".. don't add it then.
42621   //         0 is only used for filling gaps in the directly indexed bucket.
42622   // Bits [30..0] (only when MSB == allowed):
42623   //  0x7fffffff: The field is "simple" (varint, fixed32/64, string, bytes) and
42624   //      can be directly passed through in output. No recursion is needed.
42625   //  [0, 7ffffffe]: The field is a nested submessage. The value is the index
42626   //     that must be passed as first argument to the next Query() calls.
42627   //     Note that the message index is purely a monotonic counter in the
42628   //     filter bytecode, has no proto-equivalent match (unlike field ids).
42629   std::vector<uint32_t> words_;
42630 
42631   // One entry for each message index stored in the filter plus a sentinel at
42632   // the end. Maps each message index to the offset in |words_| where the the
42633   // Nth message start.
42634   // message_offset_.size() - 2 == the max message id that can be parsed.
42635   std::vector<uint32_t> message_offset_;
42636 
42637   bool suppress_logs_for_fuzzer_ = false;
42638 };
42639 
42640 }  // namespace protozero
42641 
42642 #endif  // SRC_PROTOZERO_FILTERING_FILTER_BYTECODE_PARSER_H_
42643 // gen_amalgamated begin header: src/protozero/filtering/filter_bytecode_common.h
42644 /*
42645  * Copyright (C) 2021 The Android Open Source Project
42646  *
42647  * Licensed under the Apache License, Version 2.0 (the "License");
42648  * you may not use this file except in compliance with the License.
42649  * You may obtain a copy of the License at
42650  *
42651  *      http://www.apache.org/licenses/LICENSE-2.0
42652  *
42653  * Unless required by applicable law or agreed to in writing, software
42654  * distributed under the License is distributed on an "AS IS" BASIS,
42655  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
42656  * See the License for the specific language governing permissions and
42657  * limitations under the License.
42658  */
42659 
42660 #ifndef SRC_PROTOZERO_FILTERING_FILTER_BYTECODE_COMMON_H_
42661 #define SRC_PROTOZERO_FILTERING_FILTER_BYTECODE_COMMON_H_
42662 
42663 #include <stdint.h>
42664 
42665 namespace protozero {
42666 
42667 enum FilterOpcode : uint32_t {
42668   // The immediate value is 0 in this case.
42669   kFilterOpcode_EndOfMessage = 0,
42670 
42671   // The immediate value is the id of the allowed field.
42672   kFilterOpcode_SimpleField = 1,
42673 
42674   // The immediate value is the start of the range. The next word (without
42675   // any shifting) is the length of the range.
42676   kFilterOpcode_SimpleFieldRange = 2,
42677 
42678   // The immediate value is the id of the allowed field. The next word
42679   // (without any shifting) is the index of the filter that should be used to
42680   // recurse into the nested message.
42681   kFilterOpcode_NestedField = 3,
42682 };
42683 }  // namespace protozero
42684 
42685 #endif  // SRC_PROTOZERO_FILTERING_FILTER_BYTECODE_COMMON_H_
42686 /*
42687  * Copyright (C) 2021 The Android Open Source Project
42688  *
42689  * Licensed under the Apache License, Version 2.0 (the "License");
42690  * you may not use this file except in compliance with the License.
42691  * You may obtain a copy of the License at
42692  *
42693  *      http://www.apache.org/licenses/LICENSE-2.0
42694  *
42695  * Unless required by applicable law or agreed to in writing, software
42696  * distributed under the License is distributed on an "AS IS" BASIS,
42697  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
42698  * See the License for the specific language governing permissions and
42699  * limitations under the License.
42700  */
42701 
42702 // gen_amalgamated expanded: #include "src/protozero/filtering/filter_bytecode_parser.h"
42703 
42704 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
42705 // gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
42706 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
42707 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
42708 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
42709 // gen_amalgamated expanded: #include "src/protozero/filtering/filter_bytecode_common.h"
42710 
42711 namespace protozero {
42712 
Reset()42713 void FilterBytecodeParser::Reset() {
42714   bool suppress = suppress_logs_for_fuzzer_;
42715   *this = FilterBytecodeParser();
42716   suppress_logs_for_fuzzer_ = suppress;
42717 }
42718 
Load(const void * filter_data,size_t len)42719 bool FilterBytecodeParser::Load(const void* filter_data, size_t len) {
42720   Reset();
42721   bool res = LoadInternal(static_cast<const uint8_t*>(filter_data), len);
42722   // If load fails, don't leave the parser in a half broken state.
42723   if (!res)
42724     Reset();
42725   return res;
42726 }
42727 
LoadInternal(const uint8_t * bytecode_data,size_t len)42728 bool FilterBytecodeParser::LoadInternal(const uint8_t* bytecode_data,
42729                                         size_t len) {
42730   // First unpack the varints into a plain uint32 vector, so it's easy to
42731   // iterate through them and look ahead.
42732   std::vector<uint32_t> words;
42733   bool packed_parse_err = false;
42734   words.reserve(len);  // An overestimation, but avoids reallocations.
42735   using BytecodeDecoder =
42736       PackedRepeatedFieldIterator<proto_utils::ProtoWireType::kVarInt,
42737                                   uint32_t>;
42738   for (BytecodeDecoder it(bytecode_data, len, &packed_parse_err); it; ++it)
42739     words.emplace_back(*it);
42740 
42741   if (packed_parse_err || words.empty())
42742     return false;
42743 
42744   perfetto::base::Hash hasher;
42745   for (size_t i = 0; i < words.size() - 1; ++i)
42746     hasher.Update(words[i]);
42747 
42748   uint32_t expected_csum = static_cast<uint32_t>(hasher.digest());
42749   if (expected_csum != words.back()) {
42750     if (!suppress_logs_for_fuzzer_) {
42751       PERFETTO_ELOG("Filter bytecode checksum failed. Expected: %x, actual: %x",
42752                     expected_csum, words.back());
42753     }
42754     return false;
42755   }
42756 
42757   words.pop_back();  // Pop the checksum.
42758 
42759   // Temporay storage for each message. Cleared on every END_OF_MESSAGE.
42760   std::vector<uint32_t> direct_indexed_fields;
42761   std::vector<uint32_t> ranges;
42762   uint32_t max_msg_index = 0;
42763 
42764   auto add_directly_indexed_field = [&](uint32_t field_id, uint32_t msg_id) {
42765     PERFETTO_DCHECK(field_id > 0 && field_id < kDirectlyIndexLimit);
42766     direct_indexed_fields.resize(std::max(direct_indexed_fields.size(),
42767                                           static_cast<size_t>(field_id) + 1));
42768     direct_indexed_fields[field_id] = kAllowed | msg_id;
42769   };
42770 
42771   auto add_range = [&](uint32_t id_start, uint32_t id_end, uint32_t msg_id) {
42772     PERFETTO_DCHECK(id_end > id_start);
42773     PERFETTO_DCHECK(id_start >= kDirectlyIndexLimit);
42774     ranges.emplace_back(id_start);
42775     ranges.emplace_back(id_end);
42776     ranges.emplace_back(kAllowed | msg_id);
42777   };
42778 
42779   for (size_t i = 0; i < words.size(); ++i) {
42780     const uint32_t word = words[i];
42781     const bool has_next_word = i < words.size() - 1;
42782     const uint32_t opcode = word & 0x7u;
42783     const uint32_t field_id = word >> 3;
42784 
42785     if (field_id == 0 && opcode != kFilterOpcode_EndOfMessage) {
42786       PERFETTO_DLOG("bytecode error @ word %zu, invalid field id (0)", i);
42787       return false;
42788     }
42789 
42790     if (opcode == kFilterOpcode_SimpleField ||
42791         opcode == kFilterOpcode_NestedField) {
42792       // Field words are organized as follow:
42793       // MSB: 1 if allowed, 0 if not allowed.
42794       // Remaining bits:
42795       //   Message index in the case of nested (non-simple) messages.
42796       //   0x7f..f in the case of simple messages.
42797       uint32_t msg_id;
42798       if (opcode == kFilterOpcode_SimpleField) {
42799         msg_id = kSimpleField;
42800       } else {  // FILTER_OPCODE_NESTED_FIELD
42801         // The next word in the bytecode contains the message index.
42802         if (!has_next_word) {
42803           PERFETTO_DLOG("bytecode error @ word %zu: unterminated nested field",
42804                         i);
42805           return false;
42806         }
42807         msg_id = words[++i];
42808         max_msg_index = std::max(max_msg_index, msg_id);
42809       }
42810 
42811       if (field_id < kDirectlyIndexLimit) {
42812         add_directly_indexed_field(field_id, msg_id);
42813       } else {
42814         // In the case of a large field id (rare) we waste an extra word and
42815         // represent it as a range. Doesn't make sense to introduce extra
42816         // complexity to deal with rare cases like this.
42817         add_range(field_id, field_id + 1, msg_id);
42818       }
42819     } else if (opcode == kFilterOpcode_SimpleFieldRange) {
42820       if (!has_next_word) {
42821         PERFETTO_DLOG("bytecode error @ word %zu: unterminated range", i);
42822         return false;
42823       }
42824       const uint32_t range_len = words[++i];
42825       const uint32_t range_end = field_id + range_len;  // STL-style, excl.
42826       uint32_t id = field_id;
42827 
42828       // Here's the subtle complexity: at the bytecode level, we don't know
42829       // anything about the kDirectlyIndexLimit. It is legit to define a range
42830       // that spans across the direct-indexing threshold (e.g. 126-132). In that
42831       // case we want to add all the elements < the indexing to the O(1) bucket
42832       // and add only the remaining range as a non-indexed range.
42833       for (; id < range_end && id < kDirectlyIndexLimit; ++id)
42834         add_directly_indexed_field(id, kAllowed | kSimpleField);
42835       PERFETTO_DCHECK(id >= kDirectlyIndexLimit || id == range_end);
42836       if (id < range_end)
42837         add_range(id, range_end, kSimpleField);
42838     } else if (opcode == kFilterOpcode_EndOfMessage) {
42839       // For each message append:
42840       // 1. The "header" word telling how many directly indexed fields there
42841       //    are.
42842       // 2. The words for the directly indexed fields (id < 128).
42843       // 3. The rest of the fields, encoded as ranges.
42844       // Also update the |message_offset_| index to remember the word offset for
42845       // the current message.
42846       message_offset_.emplace_back(static_cast<uint32_t>(words_.size()));
42847       words_.emplace_back(static_cast<uint32_t>(direct_indexed_fields.size()));
42848       words_.insert(words_.end(), direct_indexed_fields.begin(),
42849                     direct_indexed_fields.end());
42850       words_.insert(words_.end(), ranges.begin(), ranges.end());
42851       direct_indexed_fields.clear();
42852       ranges.clear();
42853     } else {
42854       PERFETTO_DLOG("bytecode error @ word %zu: invalid opcode (%x)", i, word);
42855       return false;
42856     }
42857   }  // (for word in bytecode).
42858 
42859   if (max_msg_index > 0 && max_msg_index >= message_offset_.size()) {
42860     PERFETTO_DLOG(
42861         "bytecode error: a message index (%u) is out of range "
42862         "(num_messages=%zu)",
42863         max_msg_index, message_offset_.size());
42864     return false;
42865   }
42866 
42867   // Add a final entry to |message_offset_| so we can tell where the last
42868   // message ends without an extra branch in the Query() hotpath.
42869   message_offset_.emplace_back(static_cast<uint32_t>(words_.size()));
42870 
42871   return true;
42872 }
42873 
Query(uint32_t msg_index,uint32_t field_id)42874 FilterBytecodeParser::QueryResult FilterBytecodeParser::Query(
42875     uint32_t msg_index,
42876     uint32_t field_id) {
42877   FilterBytecodeParser::QueryResult res{false, 0u};
42878   if (static_cast<uint64_t>(msg_index) + 1 >=
42879       static_cast<uint64_t>(message_offset_.size())) {
42880     return res;
42881   }
42882   const uint32_t start_offset = message_offset_[msg_index];
42883   // These are DCHECKs and not just CHECKS because the |words_| is populated
42884   // by the LoadInternal call above. These cannot be violated with a malformed
42885   // bytecode.
42886   PERFETTO_DCHECK(start_offset < words_.size());
42887   const uint32_t* word = &words_[start_offset];
42888   const uint32_t end_off = message_offset_[msg_index + 1];
42889   const uint32_t* const end = words_.data() + end_off;
42890   PERFETTO_DCHECK(end > word && end <= words_.data() + words_.size());
42891   const uint32_t num_directly_indexed = *(word++);
42892   PERFETTO_DCHECK(num_directly_indexed <= kDirectlyIndexLimit);
42893   PERFETTO_DCHECK(word + num_directly_indexed <= end);
42894   uint32_t field_state = 0;
42895   if (PERFETTO_LIKELY(field_id < num_directly_indexed)) {
42896     PERFETTO_DCHECK(&word[field_id] < end);
42897     field_state = word[field_id];
42898   } else {
42899     for (word = word + num_directly_indexed; word + 2 < end;) {
42900       const uint32_t range_start = *(word++);
42901       const uint32_t range_end = *(word++);
42902       const uint32_t range_state = *(word++);
42903       if (field_id >= range_start && field_id < range_end) {
42904         field_state = range_state;
42905         break;
42906       }
42907     }  // for (word in ranges)
42908   }    // if (field_id >= num_directly_indexed)
42909 
42910   res.allowed = (field_state & kAllowed) != 0;
42911   res.nested_msg_index = field_state & ~kAllowed;
42912   PERFETTO_DCHECK(res.simple_field() ||
42913                   res.nested_msg_index < message_offset_.size() - 1);
42914   return res;
42915 }
42916 
42917 }  // namespace protozero
42918 // gen_amalgamated begin source: src/protozero/filtering/message_filter.cc
42919 // gen_amalgamated begin header: src/protozero/filtering/message_filter.h
42920 // gen_amalgamated begin header: src/protozero/filtering/message_tokenizer.h
42921 /*
42922  * Copyright (C) 2021 The Android Open Source Project
42923  *
42924  * Licensed under the Apache License, Version 2.0 (the "License");
42925  * you may not use this file except in compliance with the License.
42926  * You may obtain a copy of the License at
42927  *
42928  *      http://www.apache.org/licenses/LICENSE-2.0
42929  *
42930  * Unless required by applicable law or agreed to in writing, software
42931  * distributed under the License is distributed on an "AS IS" BASIS,
42932  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
42933  * See the License for the specific language governing permissions and
42934  * limitations under the License.
42935  */
42936 
42937 #ifndef SRC_PROTOZERO_FILTERING_MESSAGE_TOKENIZER_H_
42938 #define SRC_PROTOZERO_FILTERING_MESSAGE_TOKENIZER_H_
42939 
42940 #include <stdint.h>
42941 
42942 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
42943 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
42944 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
42945 
42946 namespace protozero {
42947 
42948 // A helper class for schema-less tokenizing of protobuf messages.
42949 // This class takes a stream of proto-encoded bytes, pushed one by one in input
42950 // via Push(octet), and returns a stream of tokens (each Push() call can return
42951 // 0 or 1 token).
42952 // A "token" contains metadata about a field, specifically: its ID, its wire
42953 // type and:
42954 //  - For varint and fixed32/64 fields: its payload.
42955 //  - For string and bytes fields: the length of its payload.
42956 //    In this case the caller is supposed to "eat" those N bytes before calling
42957 //    Push() again.
42958 // Note that this class cannot differentiate between a string/bytes field or
42959 // a submessage, because they are encoded in the same way. The caller is
42960 // supposed to know whether a field can be recursed into by just keep calling
42961 // Push() or is a string that should be skipped.
42962 // This is inline to allow the compiler to see through the Push method and
42963 // avoid a function call for each byte.
42964 class MessageTokenizer {
42965  public:
42966   struct Token {
42967     uint32_t field_id;  // 0 == not valid.
42968     proto_utils::ProtoWireType type;
42969 
42970     // For kLengthDelimited, |value| represent the length of the payload.
42971     uint64_t value;
42972 
validprotozero::MessageTokenizer::Token42973     inline bool valid() const { return field_id != 0; }
operator ==protozero::MessageTokenizer::Token42974     bool operator==(const Token& o) const {
42975       return field_id == o.field_id && type == o.type && value == o.value;
42976     }
42977   };
42978 
42979   // Pushes a byte in input and returns a token, only when getting to the last
42980   // byte of each field. Specifically:
42981   // - For varint and fixed32 fields, the Token is returned after the last byte
42982   //   of the numeric payload is pushed.
42983   // - For length-delimited fields, this returns after the last byte of the
42984   //   length is pushed (i.e. right before the payload starts). The caller is
42985   //   expected to either skip the next |value| bytes (in the case of a string
42986   //   or bytes fields) or keep calling Push, in the case of a submessage.
Push(uint8_t octet)42987   inline Token Push(uint8_t octet) {
42988     using protozero::proto_utils::ProtoWireType;
42989 
42990     // Parsing a fixed32/64 field is the only case where we don't have to do
42991     // any varint decoding. This is why this block is before the remaining
42992     // switch statement below (all the rest is a varint).
42993     if (PERFETTO_UNLIKELY(state_ == kFixedIntValue)) {
42994       PERFETTO_DCHECK(fixed_int_bits_ == 32 || fixed_int_bits_ == 64);
42995       fixed_int_value_ |= static_cast<uint64_t>(octet) << fixed_int_shift_;
42996       fixed_int_shift_ += 8;
42997       if (fixed_int_shift_ < fixed_int_bits_)
42998         return Token{};  // Intermediate byte of a fixed32/64.
42999       auto wire_type = fixed_int_bits_ == 32 ? ProtoWireType::kFixed32
43000                                              : ProtoWireType::kFixed64;
43001       uint64_t fixed_int_value = fixed_int_value_;
43002       fixed_int_value_ = fixed_int_shift_ = fixed_int_bits_ = 0;
43003       state_ = kFieldPreamble;
43004       return Token{field_id_, wire_type, fixed_int_value};
43005     }
43006 
43007     // At this point either we are: (i) parsing a field preamble; (ii) parsing a
43008     // varint field paylod; (iii) parsing the length of a length-delimited
43009     // field. In all cases, we need to decode a varint before proceeding.
43010     varint_ |= static_cast<uint64_t>(octet & 0x7F) << varint_shift_;
43011     if (octet & 0x80) {
43012       varint_shift_ += 7;
43013       if (PERFETTO_UNLIKELY(varint_shift_ >= 64)) {
43014         varint_shift_ = 0;
43015         state_ = kInvalidVarInt;
43016       }
43017       return Token{};  // Still parsing a varint.
43018     }
43019 
43020     uint64_t varint = varint_;
43021     varint_ = 0;
43022     varint_shift_ = 0;
43023 
43024     switch (state_) {
43025       case kFieldPreamble: {
43026         auto field_type = static_cast<uint32_t>(varint & 7u);  // 7 = 0..0111
43027         field_id_ = static_cast<uint32_t>(varint >> 3);
43028 
43029         // The field type is legit, now check it's well formed and within
43030         // boundaries.
43031         if (field_type == static_cast<uint32_t>(ProtoWireType::kVarInt)) {
43032           state_ = kVarIntValue;
43033         } else if (field_type ==
43034                        static_cast<uint32_t>(ProtoWireType::kFixed32) ||
43035                    field_type ==
43036                        static_cast<uint32_t>(ProtoWireType::kFixed64)) {
43037           state_ = kFixedIntValue;
43038           fixed_int_shift_ = 0;
43039           fixed_int_value_ = 0;
43040           fixed_int_bits_ =
43041               field_type == static_cast<uint32_t>(ProtoWireType::kFixed32) ? 32
43042                                                                            : 64;
43043         } else if (field_type ==
43044                    static_cast<uint32_t>(ProtoWireType::kLengthDelimited)) {
43045           state_ = kLenDelimited;
43046         } else {
43047           state_ = kInvalidFieldType;
43048         }
43049         return Token{};
43050       }
43051 
43052       case kVarIntValue: {
43053         // Return the varint field payload and go back to the next field.
43054         state_ = kFieldPreamble;
43055         return Token{field_id_, ProtoWireType::kVarInt, varint};
43056       }
43057 
43058       case kLenDelimited: {
43059         const auto payload_len = varint;
43060         if (payload_len > protozero::proto_utils::kMaxMessageLength) {
43061           state_ = kMessageTooBig;
43062           return Token{};
43063         }
43064         state_ = kFieldPreamble;
43065         // At this point the caller is expected to consume the next
43066         // |payload_len| bytes.
43067         return Token{field_id_, ProtoWireType::kLengthDelimited, payload_len};
43068       }
43069 
43070       case kFixedIntValue:
43071         // Unreacheable because of the if before the switch.
43072         PERFETTO_DCHECK(false);
43073         break;
43074 
43075       // Unrecoverable error states.
43076       case kInvalidFieldType:
43077       case kMessageTooBig:
43078       case kInvalidVarInt:
43079         break;
43080     }  // switch(state_)
43081 
43082     return Token{};  // Keep GCC happy.
43083   }
43084 
43085   // Returns true if the tokenizer FSM has reached quiescence (i.e. if we are
43086   // NOT in the middle of parsing a field).
idle() const43087   bool idle() const {
43088     return state_ == kFieldPreamble && varint_shift_ == 0 &&
43089            fixed_int_shift_ == 0;
43090   }
43091 
43092   // Only for reporting parser errors in the trace.
state() const43093   uint32_t state() const { return static_cast<uint32_t>(state_); }
43094 
43095  private:
43096   enum State {
43097     kFieldPreamble = 0,  // Parsing the varint for the field preamble.
43098     kVarIntValue = 1,    // Parsing the payload of a varint field.
43099     kFixedIntValue = 2,  // Parsing the payload of a fixed32/64 field.
43100     kLenDelimited = 3,   // Parsing the length of a length-delimited field.
43101 
43102     // Unrecoverable error states:
43103     kInvalidFieldType = 4,  // Encountered an invalid field type.
43104     kMessageTooBig = 5,     // Size of the length delimited message was too big.
43105     kInvalidVarInt = 6,     // Varint larger than 64 bits.
43106   };
43107 
43108   State state_ = kFieldPreamble;
43109   uint32_t field_id_ = 0;
43110   uint64_t varint_ = 0;
43111   uint32_t varint_shift_ = 0;
43112   uint32_t fixed_int_shift_ = 0;
43113   uint32_t fixed_int_bits_ = 0;
43114   uint64_t fixed_int_value_ = 0;
43115 };
43116 
43117 }  // namespace protozero
43118 
43119 #endif  // SRC_PROTOZERO_FILTERING_MESSAGE_TOKENIZER_H_
43120 /*
43121  * Copyright (C) 2021 The Android Open Source Project
43122  *
43123  * Licensed under the Apache License, Version 2.0 (the "License");
43124  * you may not use this file except in compliance with the License.
43125  * You may obtain a copy of the License at
43126  *
43127  *      http://www.apache.org/licenses/LICENSE-2.0
43128  *
43129  * Unless required by applicable law or agreed to in writing, software
43130  * distributed under the License is distributed on an "AS IS" BASIS,
43131  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
43132  * See the License for the specific language governing permissions and
43133  * limitations under the License.
43134  */
43135 
43136 #ifndef SRC_PROTOZERO_FILTERING_MESSAGE_FILTER_H_
43137 #define SRC_PROTOZERO_FILTERING_MESSAGE_FILTER_H_
43138 
43139 #include <stdint.h>
43140 
43141 #include <memory>
43142 #include <string>
43143 #include <unordered_map>
43144 
43145 // gen_amalgamated expanded: #include "src/protozero/filtering/filter_bytecode_parser.h"
43146 // gen_amalgamated expanded: #include "src/protozero/filtering/message_tokenizer.h"
43147 
43148 namespace protozero {
43149 
43150 // A class to filter binary-encoded proto messages using an allow-list of field
43151 // ids, also known as "filter bytecode". The filter determines which fields are
43152 // allowed to be passed through in output and strips all the other fields.
43153 // See go/trace-filtering for full design.
43154 // This class takes in input:
43155 // 1) The filter bytecode, loaded once via the LoadFilterBytecode() method.
43156 // 2) A proto-encoded binary message. The message doesn't have to be contiguous,
43157 //    it can be passed as an array of arbitrarily chunked fragments.
43158 // The FilterMessage*() method returns in output a proto message, stripping out
43159 // all unknown fields. If the input is malformed (e.g., unknown proto field wire
43160 // types, lengths out of bound) the whole filtering failed and the |error| flag
43161 // of the FilteredMessage object is set to true.
43162 // The filtering operation is based on rewriting a copy of the message into a
43163 // self-allocated buffer, which is then returned in the output. The input buffer
43164 // is NOT altered.
43165 // Note also that the process of rewriting the protos gets rid of most redundant
43166 // varint encoding (if present). So even if all fields are allow-listed, the
43167 // output might NOT be bitwise identical to the input (but it will be
43168 // semantically equivalent).
43169 // Furthermore the enable_field_usage_tracking() method allows to keep track of
43170 // a histogram of allowed / denied fields. It slows down filtering and is
43171 // intended only on host tools.
43172 class MessageFilter {
43173  public:
43174   MessageFilter();
43175   ~MessageFilter();
43176 
43177   struct InputSlice {
43178     const void* data;
43179     size_t len;
43180   };
43181 
43182   struct FilteredMessage {
FilteredMessageprotozero::MessageFilter::FilteredMessage43183     FilteredMessage(std::unique_ptr<uint8_t[]> d, size_t s)
43184         : data(std::move(d)), size(s) {}
43185     std::unique_ptr<uint8_t[]> data;
43186     size_t size;  // The used bytes in |data|. This is <= sizeof(data).
43187     bool error = false;
43188   };
43189 
43190   // Loads the filter bytecode that will be used to filter any subsequent
43191   // message. Must be called before the first call to FilterMessage*().
43192   // |filter_data| must point to a byte buffer for a proto-encoded ProtoFilter
43193   // message (see proto_filter.proto).
43194   bool LoadFilterBytecode(const void* filter_data, size_t len);
43195 
43196   // This affects the filter starting point of the subsequent FilterMessage*()
43197   // calls. By default the filtering process starts from the message @ index 0,
43198   // the root message passed to proto_filter when generating the bytecode
43199   // (in typical tracing use-cases, this is perfetto.protos.Trace). However, the
43200   // caller (TracingServiceImpl) might want to filter packets from the 2nd level
43201   // (perfetto.protos.TracePacket) because the root level is pre-pended after
43202   // the fact. This call allows to change the root message for the filter.
43203   // The argument |field_ids| is an array of proto field ids and determines the
43204   // path to the new root. For instance, in the case of [1,2,3] SetFilterRoot
43205   // will identify the sub-message for the field "root.1.2.3" and use that.
43206   // In order for this to succeed all the fields in the path must be allowed
43207   // in the filter and must be a nested message type.
43208   bool SetFilterRoot(const uint32_t* field_ids, size_t num_fields);
43209 
43210   // Takes an input message, fragmented in arbitrary slices, and returns a
43211   // filtered message in output.
43212   FilteredMessage FilterMessageFragments(const InputSlice*, size_t num_slices);
43213 
43214   // Helper for tests, where the input is a contiguous buffer.
FilterMessage(const void * data,size_t len)43215   FilteredMessage FilterMessage(const void* data, size_t len) {
43216     InputSlice slice{data, len};
43217     return FilterMessageFragments(&slice, 1);
43218   }
43219 
43220   // When enabled returns a map of "field path" to "usage counter".
43221   // The key (std::string) is a binary buffer (i.e. NOT an ASCII/UTF-8 string)
43222   // which contains a varint for each field. Consider the following:
43223   // message Root { Sub1 f1 = 1; };
43224   // message Sub1 { Sub2 f2 = 7;}
43225   // message Sub2 { string f3 = 5; }
43226   // The field .f1.f2.f3 will be encoded as \x01\0x07\x05.
43227   // The value is the number of times that field has been encountered. If the
43228   // field is not allow-listed in the bytecode (the field is stripped in output)
43229   // the count will be negative.
enable_field_usage_tracking(bool x)43230   void enable_field_usage_tracking(bool x) { track_field_usage_ = x; }
field_usage() const43231   const std::unordered_map<std::string, int32_t>& field_usage() const {
43232     return field_usage_;
43233   }
43234 
43235   // Exposed only for DCHECKS in TracingServiceImpl.
root_msg_index()43236   uint32_t root_msg_index() { return root_msg_index_; }
43237 
43238  private:
43239   // This is called by FilterMessageFragments().
43240   // Inlining allows the compiler turn the per-byte call/return into a for loop,
43241   // while, at the same time, keeping the code easy to read and reason about.
43242   // It gives a 20-25% speedup (265ms vs 215ms for a 25MB trace).
43243   void FilterOneByte(uint8_t octet) PERFETTO_ALWAYS_INLINE;
43244 
43245   // No-inline because this is a slowpath (only when usage tracking is enabled).
43246   void IncrementCurrentFieldUsage(uint32_t field_id,
43247                                   bool allowed) PERFETTO_NO_INLINE;
43248 
43249   // Gets into an error state which swallows all the input and emits no output.
43250   void SetUnrecoverableErrorState();
43251 
43252   // We keep track of the the nest of messages in a stack. Each StackState
43253   // object corresponds to a level of nesting in the proto message structure.
43254   // Every time a new field of type len-delimited that has a corresponding
43255   // sub-message in the bytecode is encountered, a new StackState is pushed in
43256   // |stack_|. stack_[0] is a sentinel to prevent over-popping without adding
43257   // extra branches in the fastpath.
43258   // |stack_|. stack_[1] is the state of the root message.
43259   struct StackState {
43260     uint32_t in_bytes = 0;  // Number of input bytes processed.
43261 
43262     // When |in_bytes| reaches this value, the current state should be popped.
43263     // This is set when recursing into nested submessages. This is 0 only for
43264     // stack_[0] (we don't know the size of the root message upfront).
43265     uint32_t in_bytes_limit = 0;
43266 
43267     // This is set when a len-delimited message is encountered, either a string
43268     // or a nested submessage that is NOT allow-listed in the bytecode.
43269     // This causes input bytes to be consumed without being parsed from the
43270     // input stream. If |passthrough_eaten_bytes| == true, they will be copied
43271     // as-is in output (e.g. in the case of an allowed string/bytes field).
43272     uint32_t eat_next_bytes = 0;
43273 
43274     // Keeps tracks of the stream_writer output counter (out_.written()) then
43275     // the StackState is pushed. This is used to work out, when popping, how
43276     // many bytes have been written for the current submessage.
43277     uint32_t out_bytes_written_at_start = 0;
43278 
43279     uint32_t field_id = 0;   // The proto field id for the current message.
43280     uint32_t msg_index = 0;  // The index of the message filter in the bytecode.
43281 
43282     // This is a pointer to the proto preamble for the current submessage
43283     // (it's nullptr for stack_[0] and non-null elsewhere). This will be filled
43284     // with the actual size of the message (out_.written() -
43285     // |out_bytes_written_at_start|) when finishing (popping) the message.
43286     // This must be filled using WriteRedundantVarint(). Note that the
43287     // |size_field_len| is variable and depends on the actual length of the
43288     // input message. If the output message has roughly the same size of the
43289     // input message, the length will not be redundant.
43290     // In other words: the length of the field is reserved when the submessage
43291     // starts. At that point we know the upper-bound for the output message
43292     // (a filtered submessage can be <= the original one, but not >). So we
43293     // reserve as many bytes it takes to write the input length in varint.
43294     // Then, when the message is finalized and we know the actual output size
43295     // we backfill the field.
43296     // Consider the example of a submessage where the input size = 130 (>127,
43297     // 2 varint bytes) and the output is 120 bytes. The length will be 2 bytes
43298     // wide even though could have been encoded with just one byte.
43299     uint8_t* size_field = nullptr;
43300     uint32_t size_field_len = 0;
43301 
43302     // When true the next |eat_next_bytes| are copied as-is in output.
43303     // It seems that keeping this field at the end rather than next to
43304     // |eat_next_bytes| makes the filter a little (but measurably) faster.
43305     // (likely something related with struct layout vs cache sizes).
43306     bool passthrough_eaten_bytes = false;
43307   };
43308 
out_written()43309   uint32_t out_written() { return static_cast<uint32_t>(out_ - &out_buf_[0]); }
43310 
43311   std::unique_ptr<uint8_t[]> out_buf_;
43312   uint8_t* out_ = nullptr;
43313   uint8_t* out_end_ = nullptr;
43314   uint32_t root_msg_index_ = 0;
43315 
43316   FilterBytecodeParser filter_;
43317   MessageTokenizer tokenizer_;
43318   std::vector<StackState> stack_;
43319 
43320   bool error_ = false;
43321   bool track_field_usage_ = false;
43322   std::unordered_map<std::string, int32_t> field_usage_;
43323 };
43324 
43325 }  // namespace protozero
43326 
43327 #endif  // SRC_PROTOZERO_FILTERING_MESSAGE_FILTER_H_
43328 /*
43329  * Copyright (C) 2021 The Android Open Source Project
43330  *
43331  * Licensed under the Apache License, Version 2.0 (the "License");
43332  * you may not use this file except in compliance with the License.
43333  * You may obtain a copy of the License at
43334  *
43335  *      http://www.apache.org/licenses/LICENSE-2.0
43336  *
43337  * Unless required by applicable law or agreed to in writing, software
43338  * distributed under the License is distributed on an "AS IS" BASIS,
43339  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
43340  * See the License for the specific language governing permissions and
43341  * limitations under the License.
43342  */
43343 
43344 // gen_amalgamated expanded: #include "src/protozero/filtering/message_filter.h"
43345 
43346 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
43347 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
43348 
43349 namespace protozero {
43350 
43351 namespace {
43352 
43353 // Inline helpers to append proto fields in output. They are the equivalent of
43354 // the protozero::Message::AppendXXX() fields but don't require building and
43355 // maintaining a full protozero::Message object or dealing with scattered
43356 // output slices.
43357 // All these functions assume there is enough space in the output buffer, which
43358 // should be always the case assuming that we don't end up generating more
43359 // output than input.
43360 
AppendVarInt(uint32_t field_id,uint64_t value,uint8_t ** out)43361 inline void AppendVarInt(uint32_t field_id, uint64_t value, uint8_t** out) {
43362   *out = proto_utils::WriteVarInt(proto_utils::MakeTagVarInt(field_id), *out);
43363   *out = proto_utils::WriteVarInt(value, *out);
43364 }
43365 
43366 // For fixed32 / fixed64.
43367 template <typename INT_T /* uint32_t | uint64_t*/>
AppendFixed(uint32_t field_id,INT_T value,uint8_t ** out)43368 inline void AppendFixed(uint32_t field_id, INT_T value, uint8_t** out) {
43369   *out = proto_utils::WriteVarInt(proto_utils::MakeTagFixed<INT_T>(field_id),
43370                                   *out);
43371   memcpy(*out, &value, sizeof(value));
43372   *out += sizeof(value);
43373 }
43374 
43375 // For length-delimited (string, bytes) fields. Note: this function appends only
43376 // the proto preamble and the varint field that states the length of the payload
43377 // not the payload itself.
43378 // In the case of submessages, the caller needs to re-write the length at the
43379 // end in the in the returned memory area.
43380 // The problem here is that, because of filtering, the length of a submessage
43381 // might be < original length (the original length is still an upper-bound).
43382 // Returns a pair with: (1) the pointer where the final length should be written
43383 // into, (2) the length of the size field.
43384 // The caller must write a redundant varint to match the original size (i.e.
43385 // needs to use WriteRedundantVarInt()).
AppendLenDelim(uint32_t field_id,uint32_t len,uint8_t ** out)43386 inline std::pair<uint8_t*, uint32_t> AppendLenDelim(uint32_t field_id,
43387                                                     uint32_t len,
43388                                                     uint8_t** out) {
43389   *out = proto_utils::WriteVarInt(proto_utils::MakeTagLengthDelimited(field_id),
43390                                   *out);
43391   uint8_t* size_field_start = *out;
43392   *out = proto_utils::WriteVarInt(len, *out);
43393   const size_t size_field_len = static_cast<size_t>(*out - size_field_start);
43394   return std::make_pair(size_field_start, size_field_len);
43395 }
43396 }  // namespace
43397 
MessageFilter()43398 MessageFilter::MessageFilter() {
43399   // Push a state on the stack for the implicit root message.
43400   stack_.emplace_back();
43401 }
43402 
43403 MessageFilter::~MessageFilter() = default;
43404 
LoadFilterBytecode(const void * filter_data,size_t len)43405 bool MessageFilter::LoadFilterBytecode(const void* filter_data, size_t len) {
43406   return filter_.Load(filter_data, len);
43407 }
43408 
SetFilterRoot(const uint32_t * field_ids,size_t num_fields)43409 bool MessageFilter::SetFilterRoot(const uint32_t* field_ids,
43410                                   size_t num_fields) {
43411   uint32_t root_msg_idx = 0;
43412   for (const uint32_t* it = field_ids; it < field_ids + num_fields; ++it) {
43413     uint32_t field_id = *it;
43414     auto res = filter_.Query(root_msg_idx, field_id);
43415     if (!res.allowed || res.simple_field())
43416       return false;
43417     root_msg_idx = res.nested_msg_index;
43418   }
43419   root_msg_index_ = root_msg_idx;
43420   return true;
43421 }
43422 
FilterMessageFragments(const InputSlice * slices,size_t num_slices)43423 MessageFilter::FilteredMessage MessageFilter::FilterMessageFragments(
43424     const InputSlice* slices,
43425     size_t num_slices) {
43426   // First compute the upper bound for the output. The filtered message cannot
43427   // be > the original message.
43428   uint32_t total_len = 0;
43429   for (size_t i = 0; i < num_slices; ++i)
43430     total_len += slices[i].len;
43431   out_buf_.reset(new uint8_t[total_len]);
43432   out_ = out_buf_.get();
43433   out_end_ = out_ + total_len;
43434 
43435   // Reset the parser state.
43436   tokenizer_ = MessageTokenizer();
43437   error_ = false;
43438   stack_.clear();
43439   stack_.resize(2);
43440   // stack_[0] is a sentinel and should never be hit in nominal cases. If we
43441   // end up there we will just keep consuming the input stream and detecting
43442   // at the end, without hurting the fastpath.
43443   stack_[0].in_bytes_limit = UINT32_MAX;
43444   stack_[0].eat_next_bytes = UINT32_MAX;
43445   // stack_[1] is the actual root message.
43446   stack_[1].in_bytes_limit = total_len;
43447   stack_[1].msg_index = root_msg_index_;
43448 
43449   // Process the input data and write the output.
43450   for (size_t slice_idx = 0; slice_idx < num_slices; ++slice_idx) {
43451     const InputSlice& slice = slices[slice_idx];
43452     const uint8_t* data = static_cast<const uint8_t*>(slice.data);
43453     for (size_t i = 0; i < slice.len; ++i)
43454       FilterOneByte(data[i]);
43455   }
43456 
43457   // Construct the output object.
43458   PERFETTO_CHECK(out_ >= out_buf_.get() && out_ <= out_end_);
43459   auto used_size = static_cast<size_t>(out_ - out_buf_.get());
43460   FilteredMessage res{std::move(out_buf_), used_size};
43461   res.error = error_;
43462   if (stack_.size() != 1 || !tokenizer_.idle() ||
43463       stack_[0].in_bytes != total_len) {
43464     res.error = true;
43465   }
43466   return res;
43467 }
43468 
FilterOneByte(uint8_t octet)43469 void MessageFilter::FilterOneByte(uint8_t octet) {
43470   PERFETTO_DCHECK(!stack_.empty());
43471 
43472   auto* state = &stack_.back();
43473   StackState next_state{};
43474   bool push_next_state = false;
43475 
43476   if (state->eat_next_bytes > 0) {
43477     // This is the case where the previous tokenizer_.Push() call returned a
43478     // length delimited message which is NOT a submessage (a string or a bytes
43479     // field). We just want to consume it, and pass it through in output
43480     // if the field was allowed.
43481     --state->eat_next_bytes;
43482     if (state->passthrough_eaten_bytes)
43483       *(out_++) = octet;
43484   } else {
43485     MessageTokenizer::Token token = tokenizer_.Push(octet);
43486     // |token| will not be valid() in most cases and this is WAI. When pushing
43487     // a varint field, only the last byte yields a token, all the other bytes
43488     // return an invalid token, they just update the internal tokenizer state.
43489     if (token.valid()) {
43490       auto filter = filter_.Query(state->msg_index, token.field_id);
43491       switch (token.type) {
43492         case proto_utils::ProtoWireType::kVarInt:
43493           if (filter.allowed && filter.simple_field())
43494             AppendVarInt(token.field_id, token.value, &out_);
43495           break;
43496         case proto_utils::ProtoWireType::kFixed32:
43497           if (filter.allowed && filter.simple_field())
43498             AppendFixed(token.field_id, static_cast<uint32_t>(token.value),
43499                         &out_);
43500           break;
43501         case proto_utils::ProtoWireType::kFixed64:
43502           if (filter.allowed && filter.simple_field())
43503             AppendFixed(token.field_id, static_cast<uint64_t>(token.value),
43504                         &out_);
43505           break;
43506         case proto_utils::ProtoWireType::kLengthDelimited:
43507           // Here we have two cases:
43508           // A. A simple string/bytes field: we just want to consume the next
43509           //    bytes (the string payload), optionally passing them through in
43510           //    output if the field is allowed.
43511           // B. This is a nested submessage. In this case we want to recurse and
43512           //    push a new state on the stack.
43513           // Note that we can't tell the difference between a
43514           // "non-allowed string" and a "non-allowed submessage". But it doesn't
43515           // matter because in both cases we just want to skip the next N bytes.
43516           const auto submessage_len = static_cast<uint32_t>(token.value);
43517           auto in_bytes_left = state->in_bytes_limit - state->in_bytes - 1;
43518           if (PERFETTO_UNLIKELY(submessage_len > in_bytes_left)) {
43519             // This is a malicious / malformed string/bytes/submessage that
43520             // claims to be larger than the outer message that contains it.
43521             return SetUnrecoverableErrorState();
43522           }
43523 
43524           if (filter.allowed && !filter.simple_field() && submessage_len > 0) {
43525             // submessage_len == 0 is the edge case of a message with a 0-len
43526             // (but present) submessage. In this case, if allowed, we don't want
43527             // to push any further state (doing so would desync the FSM) but we
43528             // still want to emit it.
43529             // At this point |submessage_len| is only an upper bound. The
43530             // final message written in output can be <= the one in input,
43531             // only some of its fields might be allowed (also remember that
43532             // this class implicitly removes redundancy varint encoding of
43533             // len-delimited field lengths). The final length varint (the
43534             // return value of AppendLenDelim()) will be filled when popping
43535             // from |stack_|.
43536             auto size_field =
43537                 AppendLenDelim(token.field_id, submessage_len, &out_);
43538             push_next_state = true;
43539             next_state.field_id = token.field_id;
43540             next_state.msg_index = filter.nested_msg_index;
43541             next_state.in_bytes_limit = submessage_len;
43542             next_state.size_field = size_field.first;
43543             next_state.size_field_len = size_field.second;
43544             next_state.out_bytes_written_at_start = out_written();
43545           } else {
43546             // A string or bytes field, or a 0 length submessage.
43547             state->eat_next_bytes = submessage_len;
43548             state->passthrough_eaten_bytes = filter.allowed;
43549             if (filter.allowed)
43550               AppendLenDelim(token.field_id, submessage_len, &out_);
43551           }
43552           break;
43553       }  // switch(type)
43554 
43555       if (PERFETTO_UNLIKELY(track_field_usage_)) {
43556         IncrementCurrentFieldUsage(token.field_id, filter.allowed);
43557       }
43558     }  // if (token.valid)
43559   }    // if (eat_next_bytes == 0)
43560 
43561   ++state->in_bytes;
43562   while (state->in_bytes >= state->in_bytes_limit) {
43563     PERFETTO_DCHECK(state->in_bytes == state->in_bytes_limit);
43564     push_next_state = false;
43565 
43566     // We can't possibly write more than we read.
43567     const uint32_t msg_bytes_written = static_cast<uint32_t>(
43568         out_written() - state->out_bytes_written_at_start);
43569     PERFETTO_DCHECK(msg_bytes_written <= state->in_bytes_limit);
43570 
43571     // Backfill the length field of the
43572     proto_utils::WriteRedundantVarInt(msg_bytes_written, state->size_field,
43573                                       state->size_field_len);
43574 
43575     const uint32_t in_bytes_processes_for_last_msg = state->in_bytes;
43576     stack_.pop_back();
43577     PERFETTO_CHECK(!stack_.empty());
43578     state = &stack_.back();
43579     state->in_bytes += in_bytes_processes_for_last_msg;
43580     if (PERFETTO_UNLIKELY(!tokenizer_.idle())) {
43581       // If we hit this case, it means that we got to the end of a submessage
43582       // while decoding a field. We can't recover from this and we don't want to
43583       // propagate a broken sub-message.
43584       return SetUnrecoverableErrorState();
43585     }
43586   }
43587 
43588   if (push_next_state) {
43589     PERFETTO_DCHECK(tokenizer_.idle());
43590     stack_.emplace_back(std::move(next_state));
43591     state = &stack_.back();
43592   }
43593 }
43594 
SetUnrecoverableErrorState()43595 void MessageFilter::SetUnrecoverableErrorState() {
43596   error_ = true;
43597   stack_.clear();
43598   stack_.resize(1);
43599   auto& state = stack_[0];
43600   state.eat_next_bytes = UINT32_MAX;
43601   state.in_bytes_limit = UINT32_MAX;
43602   state.passthrough_eaten_bytes = false;
43603   out_ = out_buf_.get();  // Reset the write pointer.
43604 }
43605 
IncrementCurrentFieldUsage(uint32_t field_id,bool allowed)43606 void MessageFilter::IncrementCurrentFieldUsage(uint32_t field_id,
43607                                                bool allowed) {
43608   // Slowpath. Used mainly in offline tools and tests to workout used fields in
43609   // a proto.
43610   PERFETTO_DCHECK(track_field_usage_);
43611 
43612   // Field path contains a concatenation of varints, one for each nesting level.
43613   // e.g. y in message Root { Sub x = 2; }; message Sub { SubSub y = 7; }
43614   // is encoded as [varint(2) + varint(7)].
43615   // We use varint to take the most out of SSO (small string opt). In most cases
43616   // the path will fit in the on-stack 22 bytes, requiring no heap.
43617   std::string field_path;
43618 
43619   auto append_field_id = [&field_path](uint32_t id) {
43620     uint8_t buf[10];
43621     uint8_t* end = proto_utils::WriteVarInt(id, buf);
43622     field_path.append(reinterpret_cast<char*>(buf),
43623                       static_cast<size_t>(end - buf));
43624   };
43625 
43626   // Append all the ancestors IDs from the state stack.
43627   // The first entry of the stack has always ID 0 and we skip it (we don't know
43628   // the ID of the root message itself).
43629   PERFETTO_DCHECK(stack_.size() >= 2 && stack_[1].field_id == 0);
43630   for (size_t i = 2; i < stack_.size(); ++i)
43631     append_field_id(stack_[i].field_id);
43632   // Append the id of the field in the current message.
43633   append_field_id(field_id);
43634   field_usage_[field_path] += allowed ? 1 : -1;
43635 }
43636 
43637 }  // namespace protozero
43638 // gen_amalgamated begin source: src/tracing/core/metatrace_writer.cc
43639 // gen_amalgamated begin header: src/tracing/core/metatrace_writer.h
43640 /*
43641  * Copyright (C) 2019 The Android Open Source Project
43642  *
43643  * Licensed under the Apache License, Version 2.0 (the "License");
43644  * you may not use this file except in compliance with the License.
43645  * You may obtain a copy of the License at
43646  *
43647  *      http://www.apache.org/licenses/LICENSE-2.0
43648  *
43649  * Unless required by applicable law or agreed to in writing, software
43650  * distributed under the License is distributed on an "AS IS" BASIS,
43651  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
43652  * See the License for the specific language governing permissions and
43653  * limitations under the License.
43654  */
43655 
43656 #ifndef SRC_TRACING_CORE_METATRACE_WRITER_H_
43657 #define SRC_TRACING_CORE_METATRACE_WRITER_H_
43658 
43659 #include <functional>
43660 #include <memory>
43661 
43662 // gen_amalgamated expanded: #include "perfetto/ext/base/metatrace.h"
43663 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
43664 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
43665 
43666 namespace perfetto {
43667 
43668 namespace base {
43669 class TaskRunner;
43670 }
43671 
43672 class TraceWriter;
43673 
43674 // Complements the base::metatrace infrastructure.
43675 // It hooks a callback to metatrace::Enable() and writes metatrace events into
43676 // a TraceWriter whenever the metatrace ring buffer is half full.
43677 // It is safe to create and attempt to start multiple instances of this class,
43678 // however only the first one will succeed because the metatrace framework
43679 // doesn't support multiple instances.
43680 // This class is defined here (instead of directly in src/probes/) so it can
43681 // be reused by other components (e.g. heapprofd).
43682 class MetatraceWriter {
43683  public:
43684   static constexpr char kDataSourceName[] = "perfetto.metatrace";
43685 
43686   MetatraceWriter();
43687   ~MetatraceWriter();
43688 
43689   MetatraceWriter(const MetatraceWriter&) = delete;
43690   MetatraceWriter& operator=(const MetatraceWriter&) = delete;
43691   MetatraceWriter(MetatraceWriter&&) = delete;
43692   MetatraceWriter& operator=(MetatraceWriter&&) = delete;
43693 
43694   void Enable(base::TaskRunner*, std::unique_ptr<TraceWriter>, uint32_t tags);
43695   void Disable();
43696   void WriteAllAndFlushTraceWriter(std::function<void()> callback);
43697 
43698  private:
43699   void WriteAllAvailableEvents();
43700 
43701   bool started_ = false;
43702   base::TaskRunner* task_runner_ = nullptr;
43703   std::unique_ptr<TraceWriter> trace_writer_;
43704   PERFETTO_THREAD_CHECKER(thread_checker_)
43705   base::WeakPtrFactory<MetatraceWriter> weak_ptr_factory_;  // Keep last.
43706 };
43707 
43708 }  // namespace perfetto
43709 
43710 #endif  // SRC_TRACING_CORE_METATRACE_WRITER_H_
43711 // gen_amalgamated begin header: gen/protos/perfetto/trace/perfetto/perfetto_metatrace.pbzero.h
43712 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
43713 
43714 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PERFETTO_PERFETTO_METATRACE_PROTO_H_
43715 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PERFETTO_PERFETTO_METATRACE_PROTO_H_
43716 
43717 #include <stddef.h>
43718 #include <stdint.h>
43719 
43720 // gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
43721 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
43722 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
43723 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
43724 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
43725 
43726 namespace perfetto {
43727 namespace protos {
43728 namespace pbzero {
43729 
43730 class PerfettoMetatrace_Arg;
43731 
43732 class PerfettoMetatrace_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
43733  public:
PerfettoMetatrace_Decoder(const uint8_t * data,size_t len)43734   PerfettoMetatrace_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
PerfettoMetatrace_Decoder(const std::string & raw)43735   explicit PerfettoMetatrace_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
PerfettoMetatrace_Decoder(const::protozero::ConstBytes & raw)43736   explicit PerfettoMetatrace_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_event_id() const43737   bool has_event_id() const { return at<1>().valid(); }
event_id() const43738   uint32_t event_id() const { return at<1>().as_uint32(); }
has_counter_id() const43739   bool has_counter_id() const { return at<2>().valid(); }
counter_id() const43740   uint32_t counter_id() const { return at<2>().as_uint32(); }
has_event_name() const43741   bool has_event_name() const { return at<8>().valid(); }
event_name() const43742   ::protozero::ConstChars event_name() const { return at<8>().as_string(); }
has_counter_name() const43743   bool has_counter_name() const { return at<9>().valid(); }
counter_name() const43744   ::protozero::ConstChars counter_name() const { return at<9>().as_string(); }
has_event_duration_ns() const43745   bool has_event_duration_ns() const { return at<3>().valid(); }
event_duration_ns() const43746   uint32_t event_duration_ns() const { return at<3>().as_uint32(); }
has_counter_value() const43747   bool has_counter_value() const { return at<4>().valid(); }
counter_value() const43748   int32_t counter_value() const { return at<4>().as_int32(); }
has_thread_id() const43749   bool has_thread_id() const { return at<5>().valid(); }
thread_id() const43750   uint32_t thread_id() const { return at<5>().as_uint32(); }
has_has_overruns() const43751   bool has_has_overruns() const { return at<6>().valid(); }
has_overruns() const43752   bool has_overruns() const { return at<6>().as_bool(); }
has_args() const43753   bool has_args() const { return at<7>().valid(); }
args() const43754   ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> args() const { return GetRepeated<::protozero::ConstBytes>(7); }
43755 };
43756 
43757 class PerfettoMetatrace : public ::protozero::Message {
43758  public:
43759   using Decoder = PerfettoMetatrace_Decoder;
43760   enum : int32_t {
43761     kEventIdFieldNumber = 1,
43762     kCounterIdFieldNumber = 2,
43763     kEventNameFieldNumber = 8,
43764     kCounterNameFieldNumber = 9,
43765     kEventDurationNsFieldNumber = 3,
43766     kCounterValueFieldNumber = 4,
43767     kThreadIdFieldNumber = 5,
43768     kHasOverrunsFieldNumber = 6,
43769     kArgsFieldNumber = 7,
43770   };
43771   using Arg = ::perfetto::protos::pbzero::PerfettoMetatrace_Arg;
43772 
43773   using FieldMetadata_EventId =
43774     ::protozero::proto_utils::FieldMetadata<
43775       1,
43776       ::protozero::proto_utils::RepetitionType::kNotRepeated,
43777       ::protozero::proto_utils::ProtoSchemaType::kUint32,
43778       uint32_t,
43779       PerfettoMetatrace>;
43780 
43781   // Ceci n'est pas une pipe.
43782   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
43783   // type (and users are expected to use it as such, hence kCamelCase name).
43784   // It is declared as a function to keep protozero bindings header-only as
43785   // inline constexpr variables are not available until C++17 (while inline
43786   // functions are).
43787   // TODO(altimin): Use inline variable instead after adopting C++17.
kEventId()43788   static constexpr FieldMetadata_EventId kEventId() { return {}; }
set_event_id(uint32_t value)43789   void set_event_id(uint32_t value) {
43790     static constexpr uint32_t field_id = FieldMetadata_EventId::kFieldId;
43791     // Call the appropriate protozero::Message::Append(field_id, ...)
43792     // method based on the type of the field.
43793     ::protozero::internal::FieldWriter<
43794       ::protozero::proto_utils::ProtoSchemaType::kUint32>
43795         ::Append(*this, field_id, value);
43796   }
43797 
43798   using FieldMetadata_CounterId =
43799     ::protozero::proto_utils::FieldMetadata<
43800       2,
43801       ::protozero::proto_utils::RepetitionType::kNotRepeated,
43802       ::protozero::proto_utils::ProtoSchemaType::kUint32,
43803       uint32_t,
43804       PerfettoMetatrace>;
43805 
43806   // Ceci n'est pas une pipe.
43807   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
43808   // type (and users are expected to use it as such, hence kCamelCase name).
43809   // It is declared as a function to keep protozero bindings header-only as
43810   // inline constexpr variables are not available until C++17 (while inline
43811   // functions are).
43812   // TODO(altimin): Use inline variable instead after adopting C++17.
kCounterId()43813   static constexpr FieldMetadata_CounterId kCounterId() { return {}; }
set_counter_id(uint32_t value)43814   void set_counter_id(uint32_t value) {
43815     static constexpr uint32_t field_id = FieldMetadata_CounterId::kFieldId;
43816     // Call the appropriate protozero::Message::Append(field_id, ...)
43817     // method based on the type of the field.
43818     ::protozero::internal::FieldWriter<
43819       ::protozero::proto_utils::ProtoSchemaType::kUint32>
43820         ::Append(*this, field_id, value);
43821   }
43822 
43823   using FieldMetadata_EventName =
43824     ::protozero::proto_utils::FieldMetadata<
43825       8,
43826       ::protozero::proto_utils::RepetitionType::kNotRepeated,
43827       ::protozero::proto_utils::ProtoSchemaType::kString,
43828       std::string,
43829       PerfettoMetatrace>;
43830 
43831   // Ceci n'est pas une pipe.
43832   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
43833   // type (and users are expected to use it as such, hence kCamelCase name).
43834   // It is declared as a function to keep protozero bindings header-only as
43835   // inline constexpr variables are not available until C++17 (while inline
43836   // functions are).
43837   // TODO(altimin): Use inline variable instead after adopting C++17.
kEventName()43838   static constexpr FieldMetadata_EventName kEventName() { return {}; }
set_event_name(const char * data,size_t size)43839   void set_event_name(const char* data, size_t size) {
43840     AppendBytes(FieldMetadata_EventName::kFieldId, data, size);
43841   }
set_event_name(std::string value)43842   void set_event_name(std::string value) {
43843     static constexpr uint32_t field_id = FieldMetadata_EventName::kFieldId;
43844     // Call the appropriate protozero::Message::Append(field_id, ...)
43845     // method based on the type of the field.
43846     ::protozero::internal::FieldWriter<
43847       ::protozero::proto_utils::ProtoSchemaType::kString>
43848         ::Append(*this, field_id, value);
43849   }
43850 
43851   using FieldMetadata_CounterName =
43852     ::protozero::proto_utils::FieldMetadata<
43853       9,
43854       ::protozero::proto_utils::RepetitionType::kNotRepeated,
43855       ::protozero::proto_utils::ProtoSchemaType::kString,
43856       std::string,
43857       PerfettoMetatrace>;
43858 
43859   // Ceci n'est pas une pipe.
43860   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
43861   // type (and users are expected to use it as such, hence kCamelCase name).
43862   // It is declared as a function to keep protozero bindings header-only as
43863   // inline constexpr variables are not available until C++17 (while inline
43864   // functions are).
43865   // TODO(altimin): Use inline variable instead after adopting C++17.
kCounterName()43866   static constexpr FieldMetadata_CounterName kCounterName() { return {}; }
set_counter_name(const char * data,size_t size)43867   void set_counter_name(const char* data, size_t size) {
43868     AppendBytes(FieldMetadata_CounterName::kFieldId, data, size);
43869   }
set_counter_name(std::string value)43870   void set_counter_name(std::string value) {
43871     static constexpr uint32_t field_id = FieldMetadata_CounterName::kFieldId;
43872     // Call the appropriate protozero::Message::Append(field_id, ...)
43873     // method based on the type of the field.
43874     ::protozero::internal::FieldWriter<
43875       ::protozero::proto_utils::ProtoSchemaType::kString>
43876         ::Append(*this, field_id, value);
43877   }
43878 
43879   using FieldMetadata_EventDurationNs =
43880     ::protozero::proto_utils::FieldMetadata<
43881       3,
43882       ::protozero::proto_utils::RepetitionType::kNotRepeated,
43883       ::protozero::proto_utils::ProtoSchemaType::kUint32,
43884       uint32_t,
43885       PerfettoMetatrace>;
43886 
43887   // Ceci n'est pas une pipe.
43888   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
43889   // type (and users are expected to use it as such, hence kCamelCase name).
43890   // It is declared as a function to keep protozero bindings header-only as
43891   // inline constexpr variables are not available until C++17 (while inline
43892   // functions are).
43893   // TODO(altimin): Use inline variable instead after adopting C++17.
kEventDurationNs()43894   static constexpr FieldMetadata_EventDurationNs kEventDurationNs() { return {}; }
set_event_duration_ns(uint32_t value)43895   void set_event_duration_ns(uint32_t value) {
43896     static constexpr uint32_t field_id = FieldMetadata_EventDurationNs::kFieldId;
43897     // Call the appropriate protozero::Message::Append(field_id, ...)
43898     // method based on the type of the field.
43899     ::protozero::internal::FieldWriter<
43900       ::protozero::proto_utils::ProtoSchemaType::kUint32>
43901         ::Append(*this, field_id, value);
43902   }
43903 
43904   using FieldMetadata_CounterValue =
43905     ::protozero::proto_utils::FieldMetadata<
43906       4,
43907       ::protozero::proto_utils::RepetitionType::kNotRepeated,
43908       ::protozero::proto_utils::ProtoSchemaType::kInt32,
43909       int32_t,
43910       PerfettoMetatrace>;
43911 
43912   // Ceci n'est pas une pipe.
43913   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
43914   // type (and users are expected to use it as such, hence kCamelCase name).
43915   // It is declared as a function to keep protozero bindings header-only as
43916   // inline constexpr variables are not available until C++17 (while inline
43917   // functions are).
43918   // TODO(altimin): Use inline variable instead after adopting C++17.
kCounterValue()43919   static constexpr FieldMetadata_CounterValue kCounterValue() { return {}; }
set_counter_value(int32_t value)43920   void set_counter_value(int32_t value) {
43921     static constexpr uint32_t field_id = FieldMetadata_CounterValue::kFieldId;
43922     // Call the appropriate protozero::Message::Append(field_id, ...)
43923     // method based on the type of the field.
43924     ::protozero::internal::FieldWriter<
43925       ::protozero::proto_utils::ProtoSchemaType::kInt32>
43926         ::Append(*this, field_id, value);
43927   }
43928 
43929   using FieldMetadata_ThreadId =
43930     ::protozero::proto_utils::FieldMetadata<
43931       5,
43932       ::protozero::proto_utils::RepetitionType::kNotRepeated,
43933       ::protozero::proto_utils::ProtoSchemaType::kUint32,
43934       uint32_t,
43935       PerfettoMetatrace>;
43936 
43937   // Ceci n'est pas une pipe.
43938   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
43939   // type (and users are expected to use it as such, hence kCamelCase name).
43940   // It is declared as a function to keep protozero bindings header-only as
43941   // inline constexpr variables are not available until C++17 (while inline
43942   // functions are).
43943   // TODO(altimin): Use inline variable instead after adopting C++17.
kThreadId()43944   static constexpr FieldMetadata_ThreadId kThreadId() { return {}; }
set_thread_id(uint32_t value)43945   void set_thread_id(uint32_t value) {
43946     static constexpr uint32_t field_id = FieldMetadata_ThreadId::kFieldId;
43947     // Call the appropriate protozero::Message::Append(field_id, ...)
43948     // method based on the type of the field.
43949     ::protozero::internal::FieldWriter<
43950       ::protozero::proto_utils::ProtoSchemaType::kUint32>
43951         ::Append(*this, field_id, value);
43952   }
43953 
43954   using FieldMetadata_HasOverruns =
43955     ::protozero::proto_utils::FieldMetadata<
43956       6,
43957       ::protozero::proto_utils::RepetitionType::kNotRepeated,
43958       ::protozero::proto_utils::ProtoSchemaType::kBool,
43959       bool,
43960       PerfettoMetatrace>;
43961 
43962   // Ceci n'est pas une pipe.
43963   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
43964   // type (and users are expected to use it as such, hence kCamelCase name).
43965   // It is declared as a function to keep protozero bindings header-only as
43966   // inline constexpr variables are not available until C++17 (while inline
43967   // functions are).
43968   // TODO(altimin): Use inline variable instead after adopting C++17.
kHasOverruns()43969   static constexpr FieldMetadata_HasOverruns kHasOverruns() { return {}; }
set_has_overruns(bool value)43970   void set_has_overruns(bool value) {
43971     static constexpr uint32_t field_id = FieldMetadata_HasOverruns::kFieldId;
43972     // Call the appropriate protozero::Message::Append(field_id, ...)
43973     // method based on the type of the field.
43974     ::protozero::internal::FieldWriter<
43975       ::protozero::proto_utils::ProtoSchemaType::kBool>
43976         ::Append(*this, field_id, value);
43977   }
43978 
43979   using FieldMetadata_Args =
43980     ::protozero::proto_utils::FieldMetadata<
43981       7,
43982       ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
43983       ::protozero::proto_utils::ProtoSchemaType::kMessage,
43984       PerfettoMetatrace_Arg,
43985       PerfettoMetatrace>;
43986 
43987   // Ceci n'est pas une pipe.
43988   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
43989   // type (and users are expected to use it as such, hence kCamelCase name).
43990   // It is declared as a function to keep protozero bindings header-only as
43991   // inline constexpr variables are not available until C++17 (while inline
43992   // functions are).
43993   // TODO(altimin): Use inline variable instead after adopting C++17.
kArgs()43994   static constexpr FieldMetadata_Args kArgs() { return {}; }
add_args()43995   template <typename T = PerfettoMetatrace_Arg> T* add_args() {
43996     return BeginNestedMessage<T>(7);
43997   }
43998 
43999 };
44000 
44001 class PerfettoMetatrace_Arg_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
44002  public:
PerfettoMetatrace_Arg_Decoder(const uint8_t * data,size_t len)44003   PerfettoMetatrace_Arg_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
PerfettoMetatrace_Arg_Decoder(const std::string & raw)44004   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)44005   explicit PerfettoMetatrace_Arg_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_key() const44006   bool has_key() const { return at<1>().valid(); }
key() const44007   ::protozero::ConstChars key() const { return at<1>().as_string(); }
has_value() const44008   bool has_value() const { return at<2>().valid(); }
value() const44009   ::protozero::ConstChars value() const { return at<2>().as_string(); }
44010 };
44011 
44012 class PerfettoMetatrace_Arg : public ::protozero::Message {
44013  public:
44014   using Decoder = PerfettoMetatrace_Arg_Decoder;
44015   enum : int32_t {
44016     kKeyFieldNumber = 1,
44017     kValueFieldNumber = 2,
44018   };
44019 
44020   using FieldMetadata_Key =
44021     ::protozero::proto_utils::FieldMetadata<
44022       1,
44023       ::protozero::proto_utils::RepetitionType::kNotRepeated,
44024       ::protozero::proto_utils::ProtoSchemaType::kString,
44025       std::string,
44026       PerfettoMetatrace_Arg>;
44027 
44028   // Ceci n'est pas une pipe.
44029   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
44030   // type (and users are expected to use it as such, hence kCamelCase name).
44031   // It is declared as a function to keep protozero bindings header-only as
44032   // inline constexpr variables are not available until C++17 (while inline
44033   // functions are).
44034   // TODO(altimin): Use inline variable instead after adopting C++17.
kKey()44035   static constexpr FieldMetadata_Key kKey() { return {}; }
set_key(const char * data,size_t size)44036   void set_key(const char* data, size_t size) {
44037     AppendBytes(FieldMetadata_Key::kFieldId, data, size);
44038   }
set_key(std::string value)44039   void set_key(std::string value) {
44040     static constexpr uint32_t field_id = FieldMetadata_Key::kFieldId;
44041     // Call the appropriate protozero::Message::Append(field_id, ...)
44042     // method based on the type of the field.
44043     ::protozero::internal::FieldWriter<
44044       ::protozero::proto_utils::ProtoSchemaType::kString>
44045         ::Append(*this, field_id, value);
44046   }
44047 
44048   using FieldMetadata_Value =
44049     ::protozero::proto_utils::FieldMetadata<
44050       2,
44051       ::protozero::proto_utils::RepetitionType::kNotRepeated,
44052       ::protozero::proto_utils::ProtoSchemaType::kString,
44053       std::string,
44054       PerfettoMetatrace_Arg>;
44055 
44056   // Ceci n'est pas une pipe.
44057   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
44058   // type (and users are expected to use it as such, hence kCamelCase name).
44059   // It is declared as a function to keep protozero bindings header-only as
44060   // inline constexpr variables are not available until C++17 (while inline
44061   // functions are).
44062   // TODO(altimin): Use inline variable instead after adopting C++17.
kValue()44063   static constexpr FieldMetadata_Value kValue() { return {}; }
set_value(const char * data,size_t size)44064   void set_value(const char* data, size_t size) {
44065     AppendBytes(FieldMetadata_Value::kFieldId, data, size);
44066   }
set_value(std::string value)44067   void set_value(std::string value) {
44068     static constexpr uint32_t field_id = FieldMetadata_Value::kFieldId;
44069     // Call the appropriate protozero::Message::Append(field_id, ...)
44070     // method based on the type of the field.
44071     ::protozero::internal::FieldWriter<
44072       ::protozero::proto_utils::ProtoSchemaType::kString>
44073         ::Append(*this, field_id, value);
44074   }
44075 };
44076 
44077 } // Namespace.
44078 } // Namespace.
44079 } // Namespace.
44080 #endif  // Include guard.
44081 /*
44082  * Copyright (C) 2019 The Android Open Source Project
44083  *
44084  * Licensed under the Apache License, Version 2.0 (the "License");
44085  * you may not use this file except in compliance with the License.
44086  * You may obtain a copy of the License at
44087  *
44088  *      http://www.apache.org/licenses/LICENSE-2.0
44089  *
44090  * Unless required by applicable law or agreed to in writing, software
44091  * distributed under the License is distributed on an "AS IS" BASIS,
44092  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
44093  * See the License for the specific language governing permissions and
44094  * limitations under the License.
44095  */
44096 
44097 // gen_amalgamated expanded: #include "src/tracing/core/metatrace_writer.h"
44098 
44099 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
44100 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
44101 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
44102 // gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
44103 
44104 // gen_amalgamated expanded: #include "protos/perfetto/trace/perfetto/perfetto_metatrace.pbzero.h"
44105 // gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
44106 
44107 namespace perfetto {
44108 
44109 // static
44110 constexpr char MetatraceWriter::kDataSourceName[];
44111 
MetatraceWriter()44112 MetatraceWriter::MetatraceWriter() : weak_ptr_factory_(this) {}
44113 
~MetatraceWriter()44114 MetatraceWriter::~MetatraceWriter() {
44115   Disable();
44116 }
44117 
Enable(base::TaskRunner * task_runner,std::unique_ptr<TraceWriter> trace_writer,uint32_t tags)44118 void MetatraceWriter::Enable(base::TaskRunner* task_runner,
44119                              std::unique_ptr<TraceWriter> trace_writer,
44120                              uint32_t tags) {
44121   PERFETTO_DCHECK_THREAD(thread_checker_);
44122   if (started_) {
44123     PERFETTO_DFATAL_OR_ELOG("Metatrace already started from this instance");
44124     return;
44125   }
44126   task_runner_ = task_runner;
44127   trace_writer_ = std::move(trace_writer);
44128   auto weak_ptr = weak_ptr_factory_.GetWeakPtr();
44129   bool enabled = metatrace::Enable(
44130       [weak_ptr] {
44131         if (weak_ptr)
44132           weak_ptr->WriteAllAvailableEvents();
44133       },
44134       task_runner, tags);
44135   if (!enabled)
44136     return;
44137   started_ = true;
44138 }
44139 
Disable()44140 void MetatraceWriter::Disable() {
44141   PERFETTO_DCHECK_THREAD(thread_checker_);
44142   if (!started_)
44143     return;
44144   metatrace::Disable();
44145   started_ = false;
44146   trace_writer_.reset();
44147 }
44148 
WriteAllAvailableEvents()44149 void MetatraceWriter::WriteAllAvailableEvents() {
44150   PERFETTO_DCHECK_THREAD(thread_checker_);
44151   if (!started_)
44152     return;
44153   for (auto it = metatrace::RingBuffer::GetReadIterator(); it; ++it) {
44154     auto type_and_id = it->type_and_id.load(std::memory_order_acquire);
44155     if (type_and_id == 0)
44156       break;  // Stop at the first incomplete event.
44157 
44158     auto packet = trace_writer_->NewTracePacket();
44159     packet->set_timestamp(it->timestamp_ns());
44160     auto* evt = packet->set_perfetto_metatrace();
44161     uint16_t type = type_and_id & metatrace::Record::kTypeMask;
44162     uint16_t id = type_and_id & ~metatrace::Record::kTypeMask;
44163     if (type == metatrace::Record::kTypeCounter) {
44164       evt->set_counter_id(id);
44165       evt->set_counter_value(it->counter_value);
44166     } else {
44167       evt->set_event_id(id);
44168       evt->set_event_duration_ns(it->duration_ns);
44169     }
44170 
44171     evt->set_thread_id(static_cast<uint32_t>(it->thread_id));
44172 
44173     if (metatrace::RingBuffer::has_overruns())
44174       evt->set_has_overruns(true);
44175   }
44176   // The |it| destructor will automatically update the read index position in
44177   // the meta-trace ring buffer.
44178 }
44179 
WriteAllAndFlushTraceWriter(std::function<void ()> callback)44180 void MetatraceWriter::WriteAllAndFlushTraceWriter(
44181     std::function<void()> callback) {
44182   PERFETTO_DCHECK_THREAD(thread_checker_);
44183   if (!started_)
44184     return;
44185   WriteAllAvailableEvents();
44186   trace_writer_->Flush(std::move(callback));
44187 }
44188 
44189 }  // namespace perfetto
44190 // gen_amalgamated begin source: src/tracing/core/packet_stream_validator.cc
44191 // gen_amalgamated begin header: src/tracing/core/packet_stream_validator.h
44192 /*
44193  * Copyright (C) 2018 The Android Open Source Project
44194  *
44195  * Licensed under the Apache License, Version 2.0 (the "License");
44196  * you may not use this file except in compliance with the License.
44197  * You may obtain a copy of the License at
44198  *
44199  *      http://www.apache.org/licenses/LICENSE-2.0
44200  *
44201  * Unless required by applicable law or agreed to in writing, software
44202  * distributed under the License is distributed on an "AS IS" BASIS,
44203  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
44204  * See the License for the specific language governing permissions and
44205  * limitations under the License.
44206  */
44207 
44208 #ifndef SRC_TRACING_CORE_PACKET_STREAM_VALIDATOR_H_
44209 #define SRC_TRACING_CORE_PACKET_STREAM_VALIDATOR_H_
44210 
44211 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/slice.h"
44212 
44213 namespace perfetto {
44214 
44215 // Checks that the stream of trace packets sent by the producer is well formed.
44216 // This includes:
44217 //
44218 // - Checking that the packets are not truncated.
44219 // - There are no dangling bytes left over in the packets.
44220 // - Any trusted fields (e.g., uid) are not set.
44221 //
44222 // Note that we only validate top-level fields in the trace proto; sub-messages
44223 // are simply skipped.
44224 class PacketStreamValidator {
44225  public:
44226   PacketStreamValidator() = delete;
44227 
44228   static bool Validate(const Slices&);
44229 };
44230 
44231 }  // namespace perfetto
44232 
44233 #endif  // SRC_TRACING_CORE_PACKET_STREAM_VALIDATOR_H_
44234 /*
44235  * Copyright (C) 2018 The Android Open Source Project
44236  *
44237  * Licensed under the Apache License, Version 2.0 (the "License");
44238  * you may not use this file except in compliance with the License.
44239  * You may obtain a copy of the License at
44240  *
44241  *      http://www.apache.org/licenses/LICENSE-2.0
44242  *
44243  * Unless required by applicable law or agreed to in writing, software
44244  * distributed under the License is distributed on an "AS IS" BASIS,
44245  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
44246  * See the License for the specific language governing permissions and
44247  * limitations under the License.
44248  */
44249 
44250 // gen_amalgamated expanded: #include "src/tracing/core/packet_stream_validator.h"
44251 
44252 #include <inttypes.h>
44253 #include <stddef.h>
44254 
44255 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
44256 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
44257 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
44258 
44259 // gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
44260 
44261 namespace perfetto {
44262 
44263 namespace {
44264 
44265 using protozero::proto_utils::ProtoWireType;
44266 
44267 const uint32_t kReservedFieldIds[] = {
44268     protos::pbzero::TracePacket::kTrustedUidFieldNumber,
44269     protos::pbzero::TracePacket::kTrustedPacketSequenceIdFieldNumber,
44270     protos::pbzero::TracePacket::kTraceConfigFieldNumber,
44271     protos::pbzero::TracePacket::kTraceStatsFieldNumber,
44272     protos::pbzero::TracePacket::kCompressedPacketsFieldNumber,
44273     protos::pbzero::TracePacket::kSynchronizationMarkerFieldNumber,
44274 };
44275 
44276 // This translation unit is quite subtle and perf-sensitive. Remember to check
44277 // BM_PacketStreamValidator in perfetto_benchmarks when making changes.
44278 
44279 // Checks that a packet, spread over several slices, is well-formed and doesn't
44280 // contain reserved top-level fields.
44281 // The checking logic is based on a state-machine that skips the fields' payload
44282 // and operates as follows:
44283 //              +-------------------------------+ <-------------------------+
44284 // +----------> | Read field preamble (varint)  | <----------------------+  |
44285 // |            +-------------------------------+                        |  |
44286 // |              |              |            |                          |  |
44287 // |       <Varint>        <Fixed 32/64>     <Length-delimited field>    |  |
44288 // |          V                  |                      V                |  |
44289 // |  +------------------+       |               +--------------+        |  |
44290 // |  | Read field value |       |               | Read length  |        |  |
44291 // |  | (another varint) |       |               |   (varint)   |        |  |
44292 // |  +------------------+       |               +--------------+        |  |
44293 // |           |                 V                      V                |  |
44294 // +-----------+        +----------------+     +-----------------+       |  |
44295 //                      | Skip 4/8 Bytes |     | Skip $len Bytes |-------+  |
44296 //                      +----------------+     +-----------------+          |
44297 //                               |                                          |
44298 //                               +------------------------------------------+
44299 class ProtoFieldParserFSM {
44300  public:
44301   // This method effectively continuously parses varints (either for the field
44302   // preamble or the payload or the submessage length) and tells the caller
44303   // (the Validate() method) how many bytes to skip until the next field.
Push(uint8_t octet)44304   size_t Push(uint8_t octet) {
44305     varint_ |= static_cast<uint64_t>(octet & 0x7F) << varint_shift_;
44306     if (octet & 0x80) {
44307       varint_shift_ += 7;
44308       if (varint_shift_ >= 64) {
44309         // Do not invoke UB on next call.
44310         varint_shift_ = 0;
44311         state_ = kInvalidVarInt;
44312       }
44313       return 0;
44314     }
44315     uint64_t varint = varint_;
44316     varint_ = 0;
44317     varint_shift_ = 0;
44318 
44319     switch (state_) {
44320       case kFieldPreamble: {
44321         uint64_t field_type = varint & 7;  // 7 = 0..0111
44322         auto field_id = static_cast<uint32_t>(varint >> 3);
44323         // Check if the field id is reserved, go into an error state if it is.
44324         for (size_t i = 0; i < base::ArraySize(kReservedFieldIds); ++i) {
44325           if (field_id == kReservedFieldIds[i]) {
44326             state_ = kWroteReservedField;
44327             return 0;
44328           }
44329         }
44330         // The field type is legit, now check it's well formed and within
44331         // boundaries.
44332         if (field_type == static_cast<uint64_t>(ProtoWireType::kVarInt)) {
44333           state_ = kVarIntValue;
44334         } else if (field_type ==
44335                    static_cast<uint64_t>(ProtoWireType::kFixed32)) {
44336           return 4;
44337         } else if (field_type ==
44338                    static_cast<uint64_t>(ProtoWireType::kFixed64)) {
44339           return 8;
44340         } else if (field_type ==
44341                    static_cast<uint64_t>(ProtoWireType::kLengthDelimited)) {
44342           state_ = kLenDelimitedLen;
44343         } else {
44344           state_ = kUnknownFieldType;
44345         }
44346         return 0;
44347       }
44348 
44349       case kVarIntValue: {
44350         // Consume the int field payload and go back to the next field.
44351         state_ = kFieldPreamble;
44352         return 0;
44353       }
44354 
44355       case kLenDelimitedLen: {
44356         if (varint > protozero::proto_utils::kMaxMessageLength) {
44357           state_ = kMessageTooBig;
44358           return 0;
44359         }
44360         state_ = kFieldPreamble;
44361         return static_cast<size_t>(varint);
44362       }
44363 
44364       case kWroteReservedField:
44365       case kUnknownFieldType:
44366       case kMessageTooBig:
44367       case kInvalidVarInt:
44368         // Persistent error states.
44369         return 0;
44370 
44371     }          // switch(state_)
44372     return 0;  // To keep GCC happy.
44373   }
44374 
44375   // Queried at the end of the all payload. A message is well-formed only
44376   // if the FSM is back to the state where it should parse the next field and
44377   // hasn't started parsing any preamble.
valid() const44378   bool valid() const { return state_ == kFieldPreamble && varint_shift_ == 0; }
state() const44379   int state() const { return static_cast<int>(state_); }
44380 
44381  private:
44382   enum State {
44383     kFieldPreamble = 0,  // Parsing the varint for the field preamble.
44384     kVarIntValue,        // Parsing the varint value for the field payload.
44385     kLenDelimitedLen,    // Parsing the length of the length-delimited field.
44386 
44387     // Error states:
44388     kWroteReservedField,  // Tried to set a reserved field id.
44389     kUnknownFieldType,    // Encountered an invalid field type.
44390     kMessageTooBig,       // Size of the length delimited message was too big.
44391     kInvalidVarInt,       // VarInt larger than 64 bits.
44392   };
44393 
44394   State state_ = kFieldPreamble;
44395   uint64_t varint_ = 0;
44396   uint32_t varint_shift_ = 0;
44397 };
44398 
44399 }  // namespace
44400 
44401 // static
Validate(const Slices & slices)44402 bool PacketStreamValidator::Validate(const Slices& slices) {
44403   ProtoFieldParserFSM parser;
44404   size_t skip_bytes = 0;
44405   for (const Slice& slice : slices) {
44406     for (size_t i = 0; i < slice.size;) {
44407       const size_t skip_bytes_cur_slice = std::min(skip_bytes, slice.size - i);
44408       if (skip_bytes_cur_slice > 0) {
44409         i += skip_bytes_cur_slice;
44410         skip_bytes -= skip_bytes_cur_slice;
44411       } else {
44412         uint8_t octet = *(reinterpret_cast<const uint8_t*>(slice.start) + i);
44413         skip_bytes = parser.Push(octet);
44414         i++;
44415       }
44416     }
44417   }
44418   if (skip_bytes == 0 && parser.valid())
44419     return true;
44420 
44421   PERFETTO_DLOG("Packet validation error (state %d, skip = %zu)",
44422                 parser.state(), skip_bytes);
44423   return false;
44424 }
44425 
44426 }  // namespace perfetto
44427 // gen_amalgamated begin source: src/tracing/core/trace_buffer.cc
44428 // gen_amalgamated begin header: src/tracing/core/trace_buffer.h
44429 /*
44430  * Copyright (C) 2018 The Android Open Source Project
44431  *
44432  * Licensed under the Apache License, Version 2.0 (the "License");
44433  * you may not use this file except in compliance with the License.
44434  * You may obtain a copy of the License at
44435  *
44436  *      http://www.apache.org/licenses/LICENSE-2.0
44437  *
44438  * Unless required by applicable law or agreed to in writing, software
44439  * distributed under the License is distributed on an "AS IS" BASIS,
44440  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
44441  * See the License for the specific language governing permissions and
44442  * limitations under the License.
44443  */
44444 
44445 #ifndef SRC_TRACING_CORE_TRACE_BUFFER_H_
44446 #define SRC_TRACING_CORE_TRACE_BUFFER_H_
44447 
44448 #include <stdint.h>
44449 #include <string.h>
44450 
44451 #include <array>
44452 #include <limits>
44453 #include <map>
44454 #include <tuple>
44455 
44456 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
44457 // gen_amalgamated expanded: #include "perfetto/ext/base/paged_memory.h"
44458 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_annotations.h"
44459 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
44460 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
44461 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/slice.h"
44462 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_stats.h"
44463 
44464 namespace perfetto {
44465 
44466 class TracePacket;
44467 
44468 // The main buffer, owned by the tracing service, where all the trace data is
44469 // ultimately stored into. The service will own several instances of this class,
44470 // at least one per active consumer (as defined in the |buffers| section of
44471 // trace_config.proto) and will copy chunks from the producer's shared memory
44472 // buffers into here when a CommitData IPC is received.
44473 //
44474 // Writing into the buffer
44475 // -----------------------
44476 // Data is copied from the SMB(s) using CopyChunkUntrusted(). The buffer will
44477 // hence contain data coming from different producers and different writer
44478 // sequences, more specifically:
44479 // - The service receives data by several producer(s), identified by their ID.
44480 // - Each producer writes several sequences identified by the same WriterID.
44481 //   (they correspond to TraceWriter instances in the producer).
44482 // - Each Writer writes, in order, several chunks.
44483 // - Each chunk contains zero, one, or more TracePacket(s), or even just
44484 //   fragments of packets (when they span across several chunks).
44485 //
44486 // So at any point in time, the buffer will contain a variable number of logical
44487 // sequences identified by the {ProducerID, WriterID} tuple. Any given chunk
44488 // will only contain packets (or fragments) belonging to the same sequence.
44489 //
44490 // The buffer operates by default as a ring buffer.
44491 // It has two overwrite policies:
44492 //  1. kOverwrite (default): if the write pointer reaches the read pointer, old
44493 //     unread chunks will be overwritten by new chunks.
44494 //  2. kDiscard: if the write pointer reaches the read pointer, unread chunks
44495 //     are preserved and the new chunks are discarded. Any future write becomes
44496 //     a no-op, even if the reader manages to fully catch up. This is because
44497 //     once a chunk is discarded, the sequence of packets is broken and trying
44498 //     to recover would be too hard (also due to the fact that, at the same
44499 //     time, we allow out-of-order commits and chunk re-writes).
44500 //
44501 // Chunks are (over)written in the same order of the CopyChunkUntrusted() calls.
44502 // When overwriting old content, entire chunks are overwritten or clobbered.
44503 // The buffer never leaves a partial chunk around. Chunks' payload is copied
44504 // as-is, but their header is not and is repacked in order to keep the
44505 // ProducerID around.
44506 //
44507 // Chunks are stored in the buffer next to each other. Each chunk is prefixed by
44508 // an inline header (ChunkRecord), which contains most of the fields of the
44509 // SharedMemoryABI ChunkHeader + the ProducerID + the size of the payload.
44510 // It's a conventional binary object stream essentially, where each ChunkRecord
44511 // tells where it ends and hence where to find the next one, like this:
44512 //
44513 //          .-------------------------. 16 byte boundary
44514 //          | ChunkRecord:   16 bytes |
44515 //          | - chunk id:     4 bytes |
44516 //          | - producer id:  2 bytes |
44517 //          | - writer id:    2 bytes |
44518 //          | - #fragments:   2 bytes |
44519 //    +-----+ - record size:  2 bytes |
44520 //    |     | - flags+pad:    4 bytes |
44521 //    |     +-------------------------+
44522 //    |     |                         |
44523 //    |     :     Chunk payload       :
44524 //    |     |                         |
44525 //    |     +-------------------------+
44526 //    |     |    Optional padding     |
44527 //    +---> +-------------------------+ 16 byte boundary
44528 //          |      ChunkRecord        |
44529 //          :                         :
44530 // Chunks stored in the buffer are always rounded up to 16 bytes (that is
44531 // sizeof(ChunkRecord)), in order to avoid further inner fragmentation.
44532 // Special "padding" chunks can be put in the buffer, e.g. in the case when we
44533 // try to write a chunk of size N while the write pointer is at the end of the
44534 // buffer, but the write pointer is < N bytes from the end (and hence needs to
44535 // wrap over).
44536 // Because of this, the buffer is self-describing: the contents of the buffer
44537 // can be reconstructed by just looking at the buffer content (this will be
44538 // quite useful in future to recover the buffer from crash reports).
44539 //
44540 // However, in order to keep some operations (patching and reading) fast, a
44541 // lookaside index is maintained (in |index_|), keeping each chunk in the buffer
44542 // indexed by their {ProducerID, WriterID, ChunkID} tuple.
44543 //
44544 // Patching data out-of-band
44545 // -------------------------
44546 // This buffer also supports patching chunks' payload out-of-band, after they
44547 // have been stored. This is to allow producers to backfill the "size" fields
44548 // of the protos that spawn across several chunks, when the previous chunks are
44549 // returned to the service. The MaybePatchChunkContents() deals with the fact
44550 // that a chunk might have been lost (because of wrapping) by the time the OOB
44551 // IPC comes.
44552 //
44553 // Reading from the buffer
44554 // -----------------------
44555 // This class supports one reader only (the consumer). Reads are NOT idempotent
44556 // as they move the read cursors around. Reading back the buffer is the most
44557 // conceptually complex part. The ReadNextTracePacket() method operates with
44558 // whole packet granularity. Packets are returned only when all their fragments
44559 // are available.
44560 // This class takes care of:
44561 // - Gluing packets within the same sequence, even if they are not stored
44562 //   adjacently in the buffer.
44563 // - Re-ordering chunks within a sequence (using the ChunkID, which wraps).
44564 // - Detecting holes in packet fragments (because of loss of chunks).
44565 // Reads guarantee that packets for the same sequence are read in FIFO order
44566 // (according to their ChunkID), but don't give any guarantee about the read
44567 // order of packets from different sequences, see comments in
44568 // ReadNextTracePacket() below.
44569 class TraceBuffer {
44570  public:
44571   static const size_t InlineChunkHeaderSize;  // For test/fake_packet.{cc,h}.
44572 
44573   // See comment in the header above.
44574   enum OverwritePolicy { kOverwrite, kDiscard };
44575 
44576   // Argument for out-of-band patches applied through TryPatchChunkContents().
44577   struct Patch {
44578     // From SharedMemoryABI::kPacketHeaderSize.
44579     static constexpr size_t kSize = 4;
44580 
44581     size_t offset_untrusted;
44582     std::array<uint8_t, kSize> data;
44583   };
44584 
44585   // Identifiers that are constant for a packet sequence.
44586   struct PacketSequenceProperties {
44587     ProducerID producer_id_trusted;
44588     uid_t producer_uid_trusted;
44589     WriterID writer_id;
44590   };
44591 
44592   // Can return nullptr if the memory allocation fails.
44593   static std::unique_ptr<TraceBuffer> Create(size_t size_in_bytes,
44594                                              OverwritePolicy = kOverwrite);
44595 
44596   ~TraceBuffer();
44597 
44598   // Copies a Chunk from a producer Shared Memory Buffer into the trace buffer.
44599   // |src| points to the first packet in the SharedMemoryABI's chunk shared with
44600   // an untrusted producer. "untrusted" here means: the producer might be
44601   // malicious and might change |src| concurrently while we read it (internally
44602   // this method memcpy()-s first the chunk before processing it). None of the
44603   // arguments should be trusted, unless otherwise stated. We can trust that
44604   // |src| points to a valid memory area, but not its contents.
44605   //
44606   // This method may be called multiple times for the same chunk. In this case,
44607   // the original chunk's payload will be overridden and its number of fragments
44608   // and flags adjusted to match |num_fragments| and |chunk_flags|. The service
44609   // may use this to insert partial chunks (|chunk_complete = false|) before the
44610   // producer has committed them.
44611   //
44612   // If |chunk_complete| is |false|, the TraceBuffer will only consider the
44613   // first |num_fragments - 1| packets to be complete, since the producer may
44614   // not have finished writing the latest packet. Reading from a sequence will
44615   // also not progress past any incomplete chunks until they were rewritten with
44616   // |chunk_complete = true|, e.g. after a producer's commit.
44617   //
44618   // TODO(eseckler): Pass in a PacketStreamProperties instead of individual IDs.
44619   void CopyChunkUntrusted(ProducerID producer_id_trusted,
44620                           uid_t producer_uid_trusted,
44621                           WriterID writer_id,
44622                           ChunkID chunk_id,
44623                           uint16_t num_fragments,
44624                           uint8_t chunk_flags,
44625                           bool chunk_complete,
44626                           const uint8_t* src,
44627                           size_t size);
44628   // Applies a batch of |patches| to the given chunk, if the given chunk is
44629   // still in the buffer. Does nothing if the given ChunkID is gone.
44630   // Returns true if the chunk has been found and patched, false otherwise.
44631   // |other_patches_pending| is used to determine whether this is the only
44632   // batch of patches for the chunk or there is more.
44633   // If |other_patches_pending| == false, the chunk is marked as ready to be
44634   // consumed. If true, the state of the chunk is not altered.
44635   //
44636   // Note: If the producer is batching commits (see shared_memory_arbiter.h), it
44637   // will also attempt to do patching locally. Namely, if nested messages are
44638   // completed while the chunk on which they started is being batched (i.e.
44639   // before it has been committed to the service), the producer will apply the
44640   // respective patches to the batched chunk. These patches will not be sent to
44641   // the service - i.e. only the patches that the producer did not manage to
44642   // apply before committing the chunk will be applied here.
44643   bool TryPatchChunkContents(ProducerID,
44644                              WriterID,
44645                              ChunkID,
44646                              const Patch* patches,
44647                              size_t patches_size,
44648                              bool other_patches_pending);
44649 
44650   // To read the contents of the buffer the caller needs to:
44651   //   BeginRead()
44652   //   while (ReadNextTracePacket(packet_fragments)) { ... }
44653   // No other calls to any other method should be interleaved between
44654   // BeginRead() and ReadNextTracePacket().
44655   // Reads in the TraceBuffer are NOT idempotent.
44656   void BeginRead();
44657 
44658   // Returns the next packet in the buffer, if any, and the producer_id,
44659   // producer_uid, and writer_id of the producer/writer that wrote it (as passed
44660   // in the CopyChunkUntrusted() call). Returns false if no packets can be read
44661   // at this point. If a packet was read successfully,
44662   // |previous_packet_on_sequence_dropped| is set to |true| if the previous
44663   // packet on the sequence was dropped from the buffer before it could be read
44664   // (e.g. because its chunk was overridden due to the ring buffer wrapping or
44665   // due to an ABI violation), and to |false| otherwise.
44666   //
44667   // This function returns only complete packets. Specifically:
44668   // When there is at least one complete packet in the buffer, this function
44669   // returns true and populates the TracePacket argument with the boundaries of
44670   // each fragment for one packet.
44671   // TracePacket will have at least one slice when this function returns true.
44672   // When there are no whole packets eligible to read (e.g. we are still missing
44673   // fragments) this function returns false.
44674   // This function guarantees also that packets for a given
44675   // {ProducerID, WriterID} are read in FIFO order.
44676   // This function does not guarantee any ordering w.r.t. packets belonging to
44677   // different WriterID(s). For instance, given the following packets copied
44678   // into the buffer:
44679   //   {ProducerID: 1, WriterID: 1}: P1 P2 P3
44680   //   {ProducerID: 1, WriterID: 2}: P4 P5 P6
44681   //   {ProducerID: 2, WriterID: 1}: P7 P8 P9
44682   // The following read sequence is possible:
44683   //   P1, P4, P7, P2, P3, P5, P8, P9, P6
44684   // But the following is guaranteed to NOT happen:
44685   //   P1, P5, P7, P4 (P4 cannot come after P5)
44686   bool ReadNextTracePacket(TracePacket*,
44687                            PacketSequenceProperties* sequence_properties,
44688                            bool* previous_packet_on_sequence_dropped);
44689 
stats() const44690   const TraceStats::BufferStats& stats() const { return stats_; }
size() const44691   size_t size() const { return size_; }
44692 
44693  private:
44694   friend class TraceBufferTest;
44695 
44696   // ChunkRecord is a Chunk header stored inline in the |data_| buffer, before
44697   // the chunk payload (the packets' data). The |data_| buffer looks like this:
44698   // +---------------+------------------++---------------+-----------------+
44699   // | ChunkRecord 1 | Chunk payload 1  || ChunkRecord 2 | Chunk payload 2 | ...
44700   // +---------------+------------------++---------------+-----------------+
44701   // Most of the ChunkRecord fields are copied from SharedMemoryABI::ChunkHeader
44702   // (the chunk header used in the shared memory buffers).
44703   // A ChunkRecord can be a special "padding" record. In this case its payload
44704   // should be ignored and the record should be just skipped.
44705   //
44706   // Full page move optimization:
44707   // This struct has to be exactly (sizeof(PageHeader) + sizeof(ChunkHeader))
44708   // (from shared_memory_abi.h) to allow full page move optimizations
44709   // (TODO(primiano): not implemented yet). In the special case of moving a full
44710   // 4k page that contains only one chunk, in fact, we can just ask the kernel
44711   // to move the full SHM page (see SPLICE_F_{GIFT,MOVE}) and overlay the
44712   // ChunkRecord on top of the moved SMB's header (page + chunk header).
44713   // This special requirement is covered by static_assert(s) in the .cc file.
44714   struct ChunkRecord {
ChunkRecordperfetto::TraceBuffer::ChunkRecord44715     explicit ChunkRecord(size_t sz) : flags{0}, is_padding{0} {
44716       PERFETTO_DCHECK(sz >= sizeof(ChunkRecord) &&
44717                       sz % sizeof(ChunkRecord) == 0 && sz <= kMaxSize);
44718       size = static_cast<decltype(size)>(sz);
44719     }
44720 
is_validperfetto::TraceBuffer::ChunkRecord44721     bool is_valid() const { return size != 0; }
44722 
44723     // Keep this structure packed and exactly 16 bytes (128 bits) big.
44724 
44725     // [32 bits] Monotonic counter within the same writer_id.
44726     ChunkID chunk_id = 0;
44727 
44728     // [16 bits] ID of the Producer from which the Chunk was copied from.
44729     ProducerID producer_id = 0;
44730 
44731     // [16 bits] Unique per Producer (but not within the service).
44732     // If writer_id == kWriterIdPadding the record should just be skipped.
44733     WriterID writer_id = 0;
44734 
44735     // Number of fragments contained in the chunk.
44736     uint16_t num_fragments = 0;
44737 
44738     // Size in bytes, including sizeof(ChunkRecord) itself.
44739     uint16_t size;
44740 
44741     uint8_t flags : 6;  // See SharedMemoryABI::ChunkHeader::flags.
44742     uint8_t is_padding : 1;
44743     uint8_t unused_flag : 1;
44744 
44745     // Not strictly needed, can be reused for more fields in the future. But
44746     // right now helps to spot chunks in hex dumps.
44747     char unused[3] = {'C', 'H', 'U'};
44748 
44749     static constexpr size_t kMaxSize =
44750         std::numeric_limits<decltype(size)>::max();
44751   };
44752 
44753   // Lookaside index entry. This serves two purposes:
44754   // 1) Allow a fast lookup of ChunkRecord by their ID (the tuple
44755   //   {ProducerID, WriterID, ChunkID}). This is used when applying out-of-band
44756   //   patches to the contents of the chunks after they have been copied into
44757   //   the TraceBuffer.
44758   // 2) keep the chunks ordered by their ID. This is used when reading back.
44759   // 3) Keep metadata about the status of the chunk, e.g. whether the contents
44760   //    have been read already and should be skipped in a future read pass.
44761   // This struct should not have any field that is essential for reconstructing
44762   // the contents of the buffer from a crash dump.
44763   struct ChunkMeta {
44764     // Key used for sorting in the map.
44765     struct Key {
Keyperfetto::TraceBuffer::ChunkMeta::Key44766       Key(ProducerID p, WriterID w, ChunkID c)
44767           : producer_id{p}, writer_id{w}, chunk_id{c} {}
44768 
Keyperfetto::TraceBuffer::ChunkMeta::Key44769       explicit Key(const ChunkRecord& cr)
44770           : Key(cr.producer_id, cr.writer_id, cr.chunk_id) {}
44771 
44772       // Note that this sorting doesn't keep into account the fact that ChunkID
44773       // will wrap over at some point. The extra logic in SequenceIterator deals
44774       // with that.
operator <perfetto::TraceBuffer::ChunkMeta::Key44775       bool operator<(const Key& other) const {
44776         return std::tie(producer_id, writer_id, chunk_id) <
44777                std::tie(other.producer_id, other.writer_id, other.chunk_id);
44778       }
44779 
operator ==perfetto::TraceBuffer::ChunkMeta::Key44780       bool operator==(const Key& other) const {
44781         return std::tie(producer_id, writer_id, chunk_id) ==
44782                std::tie(other.producer_id, other.writer_id, other.chunk_id);
44783       }
44784 
operator !=perfetto::TraceBuffer::ChunkMeta::Key44785       bool operator!=(const Key& other) const { return !(*this == other); }
44786 
44787       // These fields should match at all times the corresponding fields in
44788       // the |chunk_record|. They are copied here purely for efficiency to avoid
44789       // dereferencing the buffer all the time.
44790       ProducerID producer_id;
44791       WriterID writer_id;
44792       ChunkID chunk_id;
44793     };
44794 
44795     enum IndexFlags : uint8_t {
44796       // If set, the chunk state was kChunkComplete at the time it was copied.
44797       // If unset, the chunk was still kChunkBeingWritten while copied. When
44798       // reading from the chunk's sequence, the sequence will not advance past
44799       // this chunk until this flag is set.
44800       kComplete = 1 << 0,
44801 
44802       // If set, we skipped the last packet that we read from this chunk e.g.
44803       // because we it was a continuation from a previous chunk that was dropped
44804       // or due to an ABI violation.
44805       kLastReadPacketSkipped = 1 << 1
44806     };
44807 
ChunkMetaperfetto::TraceBuffer::ChunkMeta44808     ChunkMeta(ChunkRecord* r, uint16_t p, bool complete, uint8_t f, uid_t u)
44809         : chunk_record{r}, trusted_uid{u}, flags{f}, num_fragments{p} {
44810       if (complete)
44811         index_flags = kComplete;
44812     }
44813 
is_completeperfetto::TraceBuffer::ChunkMeta44814     bool is_complete() const { return index_flags & kComplete; }
44815 
set_completeperfetto::TraceBuffer::ChunkMeta44816     void set_complete(bool complete) {
44817       if (complete) {
44818         index_flags |= kComplete;
44819       } else {
44820         index_flags &= ~kComplete;
44821       }
44822     }
44823 
last_read_packet_skippedperfetto::TraceBuffer::ChunkMeta44824     bool last_read_packet_skipped() const {
44825       return index_flags & kLastReadPacketSkipped;
44826     }
44827 
set_last_read_packet_skippedperfetto::TraceBuffer::ChunkMeta44828     void set_last_read_packet_skipped(bool skipped) {
44829       if (skipped) {
44830         index_flags |= kLastReadPacketSkipped;
44831       } else {
44832         index_flags &= ~kLastReadPacketSkipped;
44833       }
44834     }
44835 
44836     ChunkRecord* const chunk_record;  // Addr of ChunkRecord within |data_|.
44837     const uid_t trusted_uid;          // uid of the producer.
44838 
44839     // Flags set by TraceBuffer to track the state of the chunk in the index.
44840     uint8_t index_flags = 0;
44841 
44842     // Correspond to |chunk_record->flags| and |chunk_record->num_fragments|.
44843     // Copied here for performance reasons (avoids having to dereference
44844     // |chunk_record| while iterating over ChunkMeta) and to aid debugging in
44845     // case the buffer gets corrupted.
44846     uint8_t flags = 0;           // See SharedMemoryABI::ChunkHeader::flags.
44847     uint16_t num_fragments = 0;  // Total number of packet fragments.
44848 
44849     uint16_t num_fragments_read = 0;  // Number of fragments already read.
44850 
44851     // The start offset of the next fragment (the |num_fragments_read|-th) to be
44852     // read. This is the offset in bytes from the beginning of the ChunkRecord's
44853     // payload (the 1st fragment starts at |chunk_record| +
44854     // sizeof(ChunkRecord)).
44855     uint16_t cur_fragment_offset = 0;
44856   };
44857 
44858   using ChunkMap = std::map<ChunkMeta::Key, ChunkMeta>;
44859 
44860   // Allows to iterate over a sub-sequence of |index_| for all keys belonging to
44861   // the same {ProducerID,WriterID}. Furthermore takes into account the wrapping
44862   // of ChunkID. Instances are valid only as long as the |index_| is not altered
44863   // (can be used safely only between adjacent ReadNextTracePacket() calls).
44864   // The order of the iteration will proceed in the following order:
44865   // |wrapping_id| + 1 -> |seq_end|, |seq_begin| -> |wrapping_id|.
44866   // Practical example:
44867   // - Assume that kMaxChunkID == 7
44868   // - Assume that we have all 8 chunks in the range (0..7).
44869   // - Hence, |seq_begin| == c0, |seq_end| == c7
44870   // - Assume |wrapping_id| = 4 (c4 is the last chunk copied over
44871   //   through a CopyChunkUntrusted()).
44872   // The resulting iteration order will be: c5, c6, c7, c0, c1, c2, c3, c4.
44873   struct SequenceIterator {
44874     // Points to the 1st key (the one with the numerically min ChunkID).
44875     ChunkMap::iterator seq_begin;
44876 
44877     // Points one past the last key (the one with the numerically max ChunkID).
44878     ChunkMap::iterator seq_end;
44879 
44880     // Current iterator, always >= seq_begin && <= seq_end.
44881     ChunkMap::iterator cur;
44882 
44883     // The latest ChunkID written. Determines the start/end of the sequence.
44884     ChunkID wrapping_id;
44885 
is_validperfetto::TraceBuffer::SequenceIterator44886     bool is_valid() const { return cur != seq_end; }
44887 
producer_idperfetto::TraceBuffer::SequenceIterator44888     ProducerID producer_id() const {
44889       PERFETTO_DCHECK(is_valid());
44890       return cur->first.producer_id;
44891     }
44892 
writer_idperfetto::TraceBuffer::SequenceIterator44893     WriterID writer_id() const {
44894       PERFETTO_DCHECK(is_valid());
44895       return cur->first.writer_id;
44896     }
44897 
chunk_idperfetto::TraceBuffer::SequenceIterator44898     ChunkID chunk_id() const {
44899       PERFETTO_DCHECK(is_valid());
44900       return cur->first.chunk_id;
44901     }
44902 
operator *perfetto::TraceBuffer::SequenceIterator44903     ChunkMeta& operator*() {
44904       PERFETTO_DCHECK(is_valid());
44905       return cur->second;
44906     }
44907 
44908     // Moves |cur| to the next chunk in the index.
44909     // is_valid() will become false after calling this, if this was the last
44910     // entry of the sequence.
44911     void MoveNext();
44912 
MoveToEndperfetto::TraceBuffer::SequenceIterator44913     void MoveToEnd() { cur = seq_end; }
44914   };
44915 
44916   enum class ReadAheadResult {
44917     kSucceededReturnSlices,
44918     kFailedMoveToNextSequence,
44919     kFailedStayOnSameSequence,
44920   };
44921 
44922   enum class ReadPacketResult {
44923     kSucceeded,
44924     kFailedInvalidPacket,
44925     kFailedEmptyPacket,
44926   };
44927 
44928   explicit TraceBuffer(OverwritePolicy);
44929   TraceBuffer(const TraceBuffer&) = delete;
44930   TraceBuffer& operator=(const TraceBuffer&) = delete;
44931 
44932   bool Initialize(size_t size);
44933 
44934   // Returns an object that allows to iterate over chunks in the |index_| that
44935   // have the same {ProducerID, WriterID} of
44936   // |seq_begin.first.{producer,writer}_id|. |seq_begin| must be an iterator to
44937   // the first entry in the |index_| that has a different {ProducerID, WriterID}
44938   // from the previous one. It is valid for |seq_begin| to be == index_.end()
44939   // (i.e. if the index is empty). The iteration takes care of ChunkID wrapping,
44940   // by using |last_chunk_id_|.
44941   SequenceIterator GetReadIterForSequence(ChunkMap::iterator seq_begin);
44942 
44943   // Used as a last resort when a buffer corruption is detected.
44944   void ClearContentsAndResetRWCursors();
44945 
44946   // Adds a padding record of the given size (must be a multiple of
44947   // sizeof(ChunkRecord)).
44948   void AddPaddingRecord(size_t);
44949 
44950   // Look for contiguous fragment of the same packet starting from |read_iter_|.
44951   // If a contiguous packet is found, all the fragments are pushed into
44952   // TracePacket and the function returns kSucceededReturnSlices. If not, the
44953   // function returns either kFailedMoveToNextSequence or
44954   // kFailedStayOnSameSequence, telling the caller to continue looking for
44955   // packets.
44956   ReadAheadResult ReadAhead(TracePacket*);
44957 
44958   // Deletes (by marking the record invalid and removing form the index) all
44959   // chunks from |wptr_| to |wptr_| + |bytes_to_clear|.
44960   // Returns:
44961   //   * The size of the gap left between the next valid Chunk and the end of
44962   //     the deletion range.
44963   //   * 0 if no next valid chunk exists (if the buffer is still zeroed).
44964   //   * -1 if the buffer |overwrite_policy_| == kDiscard and the deletion would
44965   //     cause unread chunks to be overwritten. In this case the buffer is left
44966   //     untouched.
44967   // Graphically, assume the initial situation is the following (|wptr_| = 10).
44968   // |0        |10 (wptr_)       |30       |40                 |60
44969   // +---------+-----------------+---------+-------------------+---------+
44970   // | Chunk 1 | Chunk 2         | Chunk 3 | Chunk 4           | Chunk 5 |
44971   // +---------+-----------------+---------+-------------------+---------+
44972   //           |_________Deletion range_______|~~return value~~|
44973   //
44974   // A call to DeleteNextChunksFor(32) will remove chunks 2,3,4 and return 18
44975   // (60 - 42), the distance between chunk 5 and the end of the deletion range.
44976   ssize_t DeleteNextChunksFor(size_t bytes_to_clear);
44977 
44978   // Decodes the boundaries of the next packet (or a fragment) pointed by
44979   // ChunkMeta and pushes that into |TracePacket|. It also increments the
44980   // |num_fragments_read| counter.
44981   // TracePacket can be nullptr, in which case the read state is still advanced.
44982   // When TracePacket is not nullptr, ProducerID must also be not null and will
44983   // be updated with the ProducerID that originally wrote the chunk.
44984   ReadPacketResult ReadNextPacketInChunk(ChunkMeta*, TracePacket*);
44985 
DcheckIsAlignedAndWithinBounds(const uint8_t * ptr) const44986   void DcheckIsAlignedAndWithinBounds(const uint8_t* ptr) const {
44987     PERFETTO_DCHECK(ptr >= begin() && ptr <= end() - sizeof(ChunkRecord));
44988     PERFETTO_DCHECK(
44989         (reinterpret_cast<uintptr_t>(ptr) & (alignof(ChunkRecord) - 1)) == 0);
44990   }
44991 
GetChunkRecordAt(uint8_t * ptr)44992   ChunkRecord* GetChunkRecordAt(uint8_t* ptr) {
44993     DcheckIsAlignedAndWithinBounds(ptr);
44994     // We may be accessing a new (empty) record.
44995     data_.EnsureCommitted(
44996         static_cast<size_t>(ptr + sizeof(ChunkRecord) - begin()));
44997     return reinterpret_cast<ChunkRecord*>(ptr);
44998   }
44999 
45000   void DiscardWrite();
45001 
45002   // |src| can be nullptr (in which case |size| must be ==
45003   // record.size - sizeof(ChunkRecord)), for the case of writing a padding
45004   // 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)45005   void WriteChunkRecord(uint8_t* wptr,
45006                         const ChunkRecord& record,
45007                         const uint8_t* src,
45008                         size_t size) {
45009     // Note: |record.size| will be slightly bigger than |size| because of the
45010     // ChunkRecord header and rounding, to ensure that all ChunkRecord(s) are
45011     // multiple of sizeof(ChunkRecord). The invariant is:
45012     // record.size >= |size| + sizeof(ChunkRecord) (== if no rounding).
45013     PERFETTO_DCHECK(size <= ChunkRecord::kMaxSize);
45014     PERFETTO_DCHECK(record.size >= sizeof(record));
45015     PERFETTO_DCHECK(record.size % sizeof(record) == 0);
45016     PERFETTO_DCHECK(record.size >= size + sizeof(record));
45017     PERFETTO_CHECK(record.size <= size_to_end());
45018     DcheckIsAlignedAndWithinBounds(wptr);
45019 
45020     // We may be writing to this area for the first time.
45021     data_.EnsureCommitted(static_cast<size_t>(wptr + record.size - begin()));
45022 
45023     // Deliberately not a *D*CHECK.
45024     PERFETTO_CHECK(wptr + sizeof(record) + size <= end());
45025     memcpy(wptr, &record, sizeof(record));
45026     if (PERFETTO_LIKELY(src)) {
45027       // If the producer modifies the data in the shared memory buffer while we
45028       // are copying it to the central buffer, TSAN will (rightfully) flag that
45029       // as a race. However the entire purpose of copying the data into the
45030       // central buffer is that we can validate it without worrying that the
45031       // producer changes it from under our feet, so this race is benign. The
45032       // alternative would be to try computing which part of the buffer is safe
45033       // to read (assuming a well-behaving client), but the risk of introducing
45034       // a bug that way outweighs the benefit.
45035       PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(
45036           src, size, "Benign race when copying chunk from shared memory.")
45037       memcpy(wptr + sizeof(record), src, size);
45038     } else {
45039       PERFETTO_DCHECK(size == record.size - sizeof(record));
45040     }
45041     const size_t rounding_size = record.size - sizeof(record) - size;
45042     memset(wptr + sizeof(record) + size, 0, rounding_size);
45043   }
45044 
begin() const45045   uint8_t* begin() const { return reinterpret_cast<uint8_t*>(data_.Get()); }
end() const45046   uint8_t* end() const { return begin() + size_; }
size_to_end() const45047   size_t size_to_end() const { return static_cast<size_t>(end() - wptr_); }
45048 
45049   base::PagedMemory data_;
45050   size_t size_ = 0;            // Size in bytes of |data_|.
45051   size_t max_chunk_size_ = 0;  // Max size in bytes allowed for a chunk.
45052   uint8_t* wptr_ = nullptr;    // Write pointer.
45053 
45054   // An index that keeps track of the positions and metadata of each
45055   // ChunkRecord.
45056   ChunkMap index_;
45057 
45058   // Read iterator used for ReadNext(). It is reset by calling BeginRead().
45059   // It becomes invalid after any call to methods that alters the |index_|.
45060   SequenceIterator read_iter_;
45061 
45062   // See comments at the top of the file.
45063   OverwritePolicy overwrite_policy_ = kOverwrite;
45064 
45065   // Only used when |overwrite_policy_ == kDiscard|. This is set the first time
45066   // a write fails because it would overwrite unread chunks.
45067   bool discard_writes_ = false;
45068 
45069   // Keeps track of the highest ChunkID written for a given sequence, taking
45070   // into account a potential overflow of ChunkIDs. In the case of overflow,
45071   // stores the highest ChunkID written since the overflow.
45072   //
45073   // TODO(primiano): should clean up keys from this map. Right now it grows
45074   // without bounds (although realistically is not a problem unless we have too
45075   // many producers/writers within the same trace session).
45076   std::map<std::pair<ProducerID, WriterID>, ChunkID> last_chunk_id_written_;
45077 
45078   // Statistics about buffer usage.
45079   TraceStats::BufferStats stats_;
45080 
45081 #if PERFETTO_DCHECK_IS_ON()
45082   bool changed_since_last_read_ = false;
45083 #endif
45084 
45085   // When true disable some DCHECKs that have been put in place to detect
45086   // bugs in the producers. This is for tests that feed malicious inputs and
45087   // hence mimic a buggy producer.
45088   bool suppress_client_dchecks_for_testing_ = false;
45089 };
45090 
45091 }  // namespace perfetto
45092 
45093 #endif  // SRC_TRACING_CORE_TRACE_BUFFER_H_
45094 /*
45095  * Copyright (C) 2018 The Android Open Source Project
45096  *
45097  * Licensed under the Apache License, Version 2.0 (the "License");
45098  * you may not use this file except in compliance with the License.
45099  * You may obtain a copy of the License at
45100  *
45101  *      http://www.apache.org/licenses/LICENSE-2.0
45102  *
45103  * Unless required by applicable law or agreed to in writing, software
45104  * distributed under the License is distributed on an "AS IS" BASIS,
45105  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
45106  * See the License for the specific language governing permissions and
45107  * limitations under the License.
45108  */
45109 
45110 // gen_amalgamated expanded: #include "src/tracing/core/trace_buffer.h"
45111 
45112 #include <limits>
45113 
45114 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
45115 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
45116 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
45117 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
45118 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
45119 
45120 #define TRACE_BUFFER_VERBOSE_LOGGING() 0  // Set to 1 when debugging unittests.
45121 #if TRACE_BUFFER_VERBOSE_LOGGING()
45122 #define TRACE_BUFFER_DLOG PERFETTO_DLOG
45123 namespace {
45124 constexpr char kHexDigits[] = "0123456789abcdef";
HexDump(const uint8_t * src,size_t size)45125 std::string HexDump(const uint8_t* src, size_t size) {
45126   std::string buf;
45127   buf.reserve(4096 * 4);
45128   char line[64];
45129   char* c = line;
45130   for (size_t i = 0; i < size; i++) {
45131     *c++ = kHexDigits[(src[i] >> 4) & 0x0f];
45132     *c++ = kHexDigits[(src[i] >> 0) & 0x0f];
45133     if (i % 16 == 15) {
45134       buf.append("\n");
45135       buf.append(line);
45136       c = line;
45137     }
45138   }
45139   return buf;
45140 }
45141 }  // namespace
45142 #else
45143 #define TRACE_BUFFER_DLOG(...) void()
45144 #endif
45145 
45146 namespace perfetto {
45147 
45148 namespace {
45149 constexpr uint8_t kFirstPacketContinuesFromPrevChunk =
45150     SharedMemoryABI::ChunkHeader::kFirstPacketContinuesFromPrevChunk;
45151 constexpr uint8_t kLastPacketContinuesOnNextChunk =
45152     SharedMemoryABI::ChunkHeader::kLastPacketContinuesOnNextChunk;
45153 constexpr uint8_t kChunkNeedsPatching =
45154     SharedMemoryABI::ChunkHeader::kChunkNeedsPatching;
45155 }  // namespace.
45156 
45157 constexpr size_t TraceBuffer::ChunkRecord::kMaxSize;
45158 constexpr size_t TraceBuffer::InlineChunkHeaderSize = sizeof(ChunkRecord);
45159 
45160 // static
Create(size_t size_in_bytes,OverwritePolicy pol)45161 std::unique_ptr<TraceBuffer> TraceBuffer::Create(size_t size_in_bytes,
45162                                                  OverwritePolicy pol) {
45163   std::unique_ptr<TraceBuffer> trace_buffer(new TraceBuffer(pol));
45164   if (!trace_buffer->Initialize(size_in_bytes))
45165     return nullptr;
45166   return trace_buffer;
45167 }
45168 
TraceBuffer(OverwritePolicy pol)45169 TraceBuffer::TraceBuffer(OverwritePolicy pol) : overwrite_policy_(pol) {
45170   // See comments in ChunkRecord for the rationale of this.
45171   static_assert(sizeof(ChunkRecord) == sizeof(SharedMemoryABI::PageHeader) +
45172                                            sizeof(SharedMemoryABI::ChunkHeader),
45173                 "ChunkRecord out of sync with the layout of SharedMemoryABI");
45174 }
45175 
45176 TraceBuffer::~TraceBuffer() = default;
45177 
Initialize(size_t size)45178 bool TraceBuffer::Initialize(size_t size) {
45179   static_assert(
45180       SharedMemoryABI::kMinPageSize % sizeof(ChunkRecord) == 0,
45181       "sizeof(ChunkRecord) must be an integer divider of a page size");
45182   data_ = base::PagedMemory::Allocate(
45183       size, base::PagedMemory::kMayFail | base::PagedMemory::kDontCommit);
45184   if (!data_.IsValid()) {
45185     PERFETTO_ELOG("Trace buffer allocation failed (size: %zu)", size);
45186     return false;
45187   }
45188   size_ = size;
45189   stats_.set_buffer_size(size);
45190   max_chunk_size_ = std::min(size, ChunkRecord::kMaxSize);
45191   wptr_ = begin();
45192   index_.clear();
45193   last_chunk_id_written_.clear();
45194   read_iter_ = GetReadIterForSequence(index_.end());
45195   return true;
45196 }
45197 
45198 // Note: |src| points to a shmem region that is shared with the producer. Assume
45199 // that the producer is malicious and will change the content of |src|
45200 // 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)45201 void TraceBuffer::CopyChunkUntrusted(ProducerID producer_id_trusted,
45202                                      uid_t producer_uid_trusted,
45203                                      WriterID writer_id,
45204                                      ChunkID chunk_id,
45205                                      uint16_t num_fragments,
45206                                      uint8_t chunk_flags,
45207                                      bool chunk_complete,
45208                                      const uint8_t* src,
45209                                      size_t size) {
45210   // |record_size| = |size| + sizeof(ChunkRecord), rounded up to avoid to end
45211   // up in a fragmented state where size_to_end() < sizeof(ChunkRecord).
45212   const size_t record_size =
45213       base::AlignUp<sizeof(ChunkRecord)>(size + sizeof(ChunkRecord));
45214   if (PERFETTO_UNLIKELY(record_size > max_chunk_size_)) {
45215     stats_.set_abi_violations(stats_.abi_violations() + 1);
45216     PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
45217     return;
45218   }
45219 
45220   TRACE_BUFFER_DLOG("CopyChunk @ %lu, size=%zu", wptr_ - begin(), record_size);
45221 
45222 #if PERFETTO_DCHECK_IS_ON()
45223   changed_since_last_read_ = true;
45224 #endif
45225 
45226   // If the chunk hasn't been completed, we should only consider the first
45227   // |num_fragments - 1| packets complete. For simplicity, we simply disregard
45228   // the last one when we copy the chunk.
45229   if (PERFETTO_UNLIKELY(!chunk_complete)) {
45230     if (num_fragments > 0) {
45231       num_fragments--;
45232       // These flags should only affect the last packet in the chunk. We clear
45233       // them, so that TraceBuffer is able to look at the remaining packets in
45234       // this chunk.
45235       chunk_flags &= ~kLastPacketContinuesOnNextChunk;
45236       chunk_flags &= ~kChunkNeedsPatching;
45237     }
45238   }
45239 
45240   ChunkRecord record(record_size);
45241   record.producer_id = producer_id_trusted;
45242   record.chunk_id = chunk_id;
45243   record.writer_id = writer_id;
45244   record.num_fragments = num_fragments;
45245   record.flags = chunk_flags;
45246   ChunkMeta::Key key(record);
45247 
45248   // Check whether we have already copied the same chunk previously. This may
45249   // happen if the service scrapes chunks in a potentially incomplete state
45250   // before receiving commit requests for them from the producer. Note that the
45251   // service may scrape and thus override chunks in arbitrary order since the
45252   // chunks aren't ordered in the SMB.
45253   const auto it = index_.find(key);
45254   if (PERFETTO_UNLIKELY(it != index_.end())) {
45255     ChunkMeta* record_meta = &it->second;
45256     ChunkRecord* prev = record_meta->chunk_record;
45257 
45258     // Verify that the old chunk's metadata corresponds to the new one.
45259     // Overridden chunks should never change size, since the page layout is
45260     // fixed per writer. The number of fragments should also never decrease and
45261     // flags should not be removed.
45262     if (PERFETTO_UNLIKELY(ChunkMeta::Key(*prev) != key ||
45263                           prev->size != record_size ||
45264                           prev->num_fragments > num_fragments ||
45265                           (prev->flags & chunk_flags) != prev->flags)) {
45266       stats_.set_abi_violations(stats_.abi_violations() + 1);
45267       PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
45268       return;
45269     }
45270 
45271     // If this chunk was previously copied with the same number of fragments and
45272     // the number didn't change, there's no need to copy it again. If the
45273     // previous chunk was complete already, this should always be the case.
45274     PERFETTO_DCHECK(suppress_client_dchecks_for_testing_ ||
45275                     !record_meta->is_complete() ||
45276                     (chunk_complete && prev->num_fragments == num_fragments));
45277     if (prev->num_fragments == num_fragments) {
45278       TRACE_BUFFER_DLOG("  skipping recommit of identical chunk");
45279       return;
45280     }
45281 
45282     // If we've already started reading from chunk N+1 following this chunk N,
45283     // don't override chunk N. Otherwise we may end up reading a packet from
45284     // chunk N after having read from chunk N+1, thereby violating sequential
45285     // read of packets. This shouldn't happen if the producer is well-behaved,
45286     // because it shouldn't start chunk N+1 before completing chunk N.
45287     ChunkMeta::Key subsequent_key = key;
45288     static_assert(std::numeric_limits<ChunkID>::max() == kMaxChunkID,
45289                   "ChunkID wraps");
45290     subsequent_key.chunk_id++;
45291     const auto subsequent_it = index_.find(subsequent_key);
45292     if (subsequent_it != index_.end() &&
45293         subsequent_it->second.num_fragments_read > 0) {
45294       stats_.set_abi_violations(stats_.abi_violations() + 1);
45295       PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
45296       return;
45297     }
45298 
45299     // We should not have read past the last packet.
45300     if (record_meta->num_fragments_read > prev->num_fragments) {
45301       PERFETTO_ELOG(
45302           "TraceBuffer read too many fragments from an incomplete chunk");
45303       PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
45304       return;
45305     }
45306 
45307     uint8_t* wptr = reinterpret_cast<uint8_t*>(prev);
45308     TRACE_BUFFER_DLOG("  overriding chunk @ %lu, size=%zu", wptr - begin(),
45309                       record_size);
45310 
45311     // Update chunk meta data stored in the index, as it may have changed.
45312     record_meta->num_fragments = num_fragments;
45313     record_meta->flags = chunk_flags;
45314     record_meta->set_complete(chunk_complete);
45315 
45316     // Override the ChunkRecord contents at the original |wptr|.
45317     TRACE_BUFFER_DLOG("  copying @ [%lu - %lu] %zu", wptr - begin(),
45318                       uintptr_t(wptr - begin()) + record_size, record_size);
45319     WriteChunkRecord(wptr, record, src, size);
45320     TRACE_BUFFER_DLOG("Chunk raw: %s", HexDump(wptr, record_size).c_str());
45321     stats_.set_chunks_rewritten(stats_.chunks_rewritten() + 1);
45322     return;
45323   }
45324 
45325   if (PERFETTO_UNLIKELY(discard_writes_))
45326     return DiscardWrite();
45327 
45328   // If there isn't enough room from the given write position. Write a padding
45329   // record to clear the end of the buffer and wrap back.
45330   const size_t cached_size_to_end = size_to_end();
45331   if (PERFETTO_UNLIKELY(record_size > cached_size_to_end)) {
45332     ssize_t res = DeleteNextChunksFor(cached_size_to_end);
45333     if (res == -1)
45334       return DiscardWrite();
45335     PERFETTO_DCHECK(static_cast<size_t>(res) <= cached_size_to_end);
45336     AddPaddingRecord(cached_size_to_end);
45337     wptr_ = begin();
45338     stats_.set_write_wrap_count(stats_.write_wrap_count() + 1);
45339     PERFETTO_DCHECK(size_to_end() >= record_size);
45340   }
45341 
45342   // At this point either |wptr_| points to an untouched part of the buffer
45343   // (i.e. *wptr_ == 0) or we are about to overwrite one or more ChunkRecord(s).
45344   // In the latter case we need to first figure out where the next valid
45345   // ChunkRecord is (if it exists) and add padding between the new record.
45346   // Example ((w) == write cursor):
45347   //
45348   // Initial state (wtpr_ == 0):
45349   // |0 (w)    |10               |30                  |50
45350   // +---------+-----------------+--------------------+--------------------+
45351   // | Chunk 1 | Chunk 2         | Chunk 3            | Chunk 4            |
45352   // +---------+-----------------+--------------------+--------------------+
45353   //
45354   // Let's assume we now want now write a 5th Chunk of size == 35. The final
45355   // state should look like this:
45356   // |0                                |35 (w)         |50
45357   // +---------------------------------+---------------+--------------------+
45358   // | Chunk 5                         | Padding Chunk | Chunk 4            |
45359   // +---------------------------------+---------------+--------------------+
45360 
45361   // Deletes all chunks from |wptr_| to |wptr_| + |record_size|.
45362   ssize_t del_res = DeleteNextChunksFor(record_size);
45363   if (del_res == -1)
45364     return DiscardWrite();
45365   size_t padding_size = static_cast<size_t>(del_res);
45366 
45367   // Now first insert the new chunk. At the end, if necessary, add the padding.
45368   stats_.set_chunks_written(stats_.chunks_written() + 1);
45369   stats_.set_bytes_written(stats_.bytes_written() + record_size);
45370   auto it_and_inserted = index_.emplace(
45371       key, ChunkMeta(GetChunkRecordAt(wptr_), num_fragments, chunk_complete,
45372                      chunk_flags, producer_uid_trusted));
45373   PERFETTO_DCHECK(it_and_inserted.second);
45374   TRACE_BUFFER_DLOG("  copying @ [%lu - %lu] %zu", wptr_ - begin(),
45375                     uintptr_t(wptr_ - begin()) + record_size, record_size);
45376   WriteChunkRecord(wptr_, record, src, size);
45377   TRACE_BUFFER_DLOG("Chunk raw: %s", HexDump(wptr_, record_size).c_str());
45378   wptr_ += record_size;
45379   if (wptr_ >= end()) {
45380     PERFETTO_DCHECK(padding_size == 0);
45381     wptr_ = begin();
45382     stats_.set_write_wrap_count(stats_.write_wrap_count() + 1);
45383   }
45384   DcheckIsAlignedAndWithinBounds(wptr_);
45385 
45386   // Chunks may be received out of order, so only update last_chunk_id if the
45387   // new chunk_id is larger. But take into account overflows by only selecting
45388   // the new ID if its distance to the latest ID is smaller than half the number
45389   // space.
45390   //
45391   // This accounts for both the case where the new ID has just overflown and
45392   // last_chunk_id be updated even though it's smaller (e.g. |chunk_id| = 1 and
45393   // |last_chunk_id| = kMaxChunkId; chunk_id - last_chunk_id = 0) and the case
45394   // where the new ID is an out-of-order ID right after an overflow and
45395   // last_chunk_id shouldn't be updated even though it's larger (e.g. |chunk_id|
45396   // = kMaxChunkId and |last_chunk_id| = 1; chunk_id - last_chunk_id =
45397   // kMaxChunkId - 1).
45398   auto producer_and_writer_id = std::make_pair(producer_id_trusted, writer_id);
45399   ChunkID& last_chunk_id = last_chunk_id_written_[producer_and_writer_id];
45400   static_assert(std::numeric_limits<ChunkID>::max() == kMaxChunkID,
45401                 "This code assumes that ChunkID wraps at kMaxChunkID");
45402   if (chunk_id - last_chunk_id < kMaxChunkID / 2) {
45403     last_chunk_id = chunk_id;
45404   } else {
45405     stats_.set_chunks_committed_out_of_order(
45406         stats_.chunks_committed_out_of_order() + 1);
45407   }
45408 
45409   if (padding_size)
45410     AddPaddingRecord(padding_size);
45411 }
45412 
DeleteNextChunksFor(size_t bytes_to_clear)45413 ssize_t TraceBuffer::DeleteNextChunksFor(size_t bytes_to_clear) {
45414   PERFETTO_CHECK(!discard_writes_);
45415 
45416   // Find the position of the first chunk which begins at or after
45417   // (|wptr_| + |bytes|). Note that such a chunk might not exist and we might
45418   // either reach the end of the buffer or a zeroed region of the buffer.
45419   uint8_t* next_chunk_ptr = wptr_;
45420   uint8_t* search_end = wptr_ + bytes_to_clear;
45421   TRACE_BUFFER_DLOG("Delete [%zu %zu]", wptr_ - begin(), search_end - begin());
45422   DcheckIsAlignedAndWithinBounds(wptr_);
45423   PERFETTO_DCHECK(search_end <= end());
45424   std::vector<ChunkMap::iterator> index_delete;
45425   uint64_t chunks_overwritten = stats_.chunks_overwritten();
45426   uint64_t bytes_overwritten = stats_.bytes_overwritten();
45427   uint64_t padding_bytes_cleared = stats_.padding_bytes_cleared();
45428   while (next_chunk_ptr < search_end) {
45429     const ChunkRecord& next_chunk = *GetChunkRecordAt(next_chunk_ptr);
45430     TRACE_BUFFER_DLOG(
45431         "  scanning chunk [%zu %zu] (valid=%d)", next_chunk_ptr - begin(),
45432         next_chunk_ptr - begin() + next_chunk.size, next_chunk.is_valid());
45433 
45434     // We just reached the untouched part of the buffer, it's going to be all
45435     // zeroes from here to end().
45436     // Optimization: if during Initialize() we fill the buffer with padding
45437     // records we could get rid of this branch.
45438     if (PERFETTO_UNLIKELY(!next_chunk.is_valid())) {
45439       // This should happen only at the first iteration. The zeroed area can
45440       // only begin precisely at the |wptr_|, not after. Otherwise it means that
45441       // we wrapped but screwed up the ChunkRecord chain.
45442       PERFETTO_DCHECK(next_chunk_ptr == wptr_);
45443       return 0;
45444     }
45445 
45446     // Remove |next_chunk| from the index, unless it's a padding record (padding
45447     // records are not part of the index).
45448     if (PERFETTO_LIKELY(!next_chunk.is_padding)) {
45449       ChunkMeta::Key key(next_chunk);
45450       auto it = index_.find(key);
45451       bool will_remove = false;
45452       if (PERFETTO_LIKELY(it != index_.end())) {
45453         const ChunkMeta& meta = it->second;
45454         if (PERFETTO_UNLIKELY(meta.num_fragments_read < meta.num_fragments)) {
45455           if (overwrite_policy_ == kDiscard)
45456             return -1;
45457           chunks_overwritten++;
45458           bytes_overwritten += next_chunk.size;
45459         }
45460         index_delete.push_back(it);
45461         will_remove = true;
45462       }
45463       TRACE_BUFFER_DLOG(
45464           "  del index {%" PRIu32 ",%" PRIu32 ",%u} @ [%lu - %lu] %d",
45465           key.producer_id, key.writer_id, key.chunk_id,
45466           next_chunk_ptr - begin(), next_chunk_ptr - begin() + next_chunk.size,
45467           will_remove);
45468       PERFETTO_DCHECK(will_remove);
45469     } else {
45470       padding_bytes_cleared += next_chunk.size;
45471     }
45472 
45473     next_chunk_ptr += next_chunk.size;
45474 
45475     // We should never hit this, unless we managed to screw up while writing
45476     // to the buffer and breaking the ChunkRecord(s) chain.
45477     // TODO(primiano): Write more meaningful logging with the status of the
45478     // buffer, to get more actionable bugs in case we hit this.
45479     PERFETTO_CHECK(next_chunk_ptr <= end());
45480   }
45481 
45482   // Remove from the index.
45483   for (auto it : index_delete) {
45484     index_.erase(it);
45485   }
45486   stats_.set_chunks_overwritten(chunks_overwritten);
45487   stats_.set_bytes_overwritten(bytes_overwritten);
45488   stats_.set_padding_bytes_cleared(padding_bytes_cleared);
45489 
45490   PERFETTO_DCHECK(next_chunk_ptr >= search_end && next_chunk_ptr <= end());
45491   return static_cast<ssize_t>(next_chunk_ptr - search_end);
45492 }
45493 
AddPaddingRecord(size_t size)45494 void TraceBuffer::AddPaddingRecord(size_t size) {
45495   PERFETTO_DCHECK(size >= sizeof(ChunkRecord) && size <= ChunkRecord::kMaxSize);
45496   ChunkRecord record(size);
45497   record.is_padding = 1;
45498   TRACE_BUFFER_DLOG("AddPaddingRecord @ [%lu - %lu] %zu", wptr_ - begin(),
45499                     uintptr_t(wptr_ - begin()) + size, size);
45500   WriteChunkRecord(wptr_, record, nullptr, size - sizeof(ChunkRecord));
45501   stats_.set_padding_bytes_written(stats_.padding_bytes_written() + size);
45502   // |wptr_| is deliberately not advanced when writing a padding record.
45503 }
45504 
TryPatchChunkContents(ProducerID producer_id,WriterID writer_id,ChunkID chunk_id,const Patch * patches,size_t patches_size,bool other_patches_pending)45505 bool TraceBuffer::TryPatchChunkContents(ProducerID producer_id,
45506                                         WriterID writer_id,
45507                                         ChunkID chunk_id,
45508                                         const Patch* patches,
45509                                         size_t patches_size,
45510                                         bool other_patches_pending) {
45511   ChunkMeta::Key key(producer_id, writer_id, chunk_id);
45512   auto it = index_.find(key);
45513   if (it == index_.end()) {
45514     stats_.set_patches_failed(stats_.patches_failed() + 1);
45515     return false;
45516   }
45517   ChunkMeta& chunk_meta = it->second;
45518 
45519   // Check that the index is consistent with the actual ProducerID/WriterID
45520   // stored in the ChunkRecord.
45521   PERFETTO_DCHECK(ChunkMeta::Key(*chunk_meta.chunk_record) == key);
45522   uint8_t* chunk_begin = reinterpret_cast<uint8_t*>(chunk_meta.chunk_record);
45523   PERFETTO_DCHECK(chunk_begin >= begin());
45524   uint8_t* chunk_end = chunk_begin + chunk_meta.chunk_record->size;
45525   PERFETTO_DCHECK(chunk_end <= end());
45526 
45527   static_assert(Patch::kSize == SharedMemoryABI::kPacketHeaderSize,
45528                 "Patch::kSize out of sync with SharedMemoryABI");
45529 
45530   for (size_t i = 0; i < patches_size; i++) {
45531     uint8_t* ptr =
45532         chunk_begin + sizeof(ChunkRecord) + patches[i].offset_untrusted;
45533     TRACE_BUFFER_DLOG("PatchChunk {%" PRIu32 ",%" PRIu32
45534                       ",%u} size=%zu @ %zu with {%02x %02x %02x %02x} cur "
45535                       "{%02x %02x %02x %02x}",
45536                       producer_id, writer_id, chunk_id, chunk_end - chunk_begin,
45537                       patches[i].offset_untrusted, patches[i].data[0],
45538                       patches[i].data[1], patches[i].data[2],
45539                       patches[i].data[3], ptr[0], ptr[1], ptr[2], ptr[3]);
45540     if (ptr < chunk_begin + sizeof(ChunkRecord) ||
45541         ptr > chunk_end - Patch::kSize) {
45542       // Either the IPC was so slow and in the meantime the writer managed to
45543       // wrap over |chunk_id| or the producer sent a malicious IPC.
45544       stats_.set_patches_failed(stats_.patches_failed() + 1);
45545       return false;
45546     }
45547 
45548     // DCHECK that we are writing into a zero-filled size field and not into
45549     // valid data. It relies on ScatteredStreamWriter::ReserveBytes() to
45550     // zero-fill reservations in debug builds.
45551     char zero[Patch::kSize]{};
45552     PERFETTO_DCHECK(memcmp(ptr, &zero, Patch::kSize) == 0);
45553 
45554     memcpy(ptr, &patches[i].data[0], Patch::kSize);
45555   }
45556   TRACE_BUFFER_DLOG(
45557       "Chunk raw (after patch): %s",
45558       HexDump(chunk_begin, chunk_meta.chunk_record->size).c_str());
45559 
45560   stats_.set_patches_succeeded(stats_.patches_succeeded() + patches_size);
45561   if (!other_patches_pending) {
45562     chunk_meta.flags &= ~kChunkNeedsPatching;
45563     chunk_meta.chunk_record->flags = chunk_meta.flags;
45564   }
45565   return true;
45566 }
45567 
BeginRead()45568 void TraceBuffer::BeginRead() {
45569   read_iter_ = GetReadIterForSequence(index_.begin());
45570 #if PERFETTO_DCHECK_IS_ON()
45571   changed_since_last_read_ = false;
45572 #endif
45573 }
45574 
GetReadIterForSequence(ChunkMap::iterator seq_begin)45575 TraceBuffer::SequenceIterator TraceBuffer::GetReadIterForSequence(
45576     ChunkMap::iterator seq_begin) {
45577   SequenceIterator iter;
45578   iter.seq_begin = seq_begin;
45579   if (seq_begin == index_.end()) {
45580     iter.cur = iter.seq_end = index_.end();
45581     return iter;
45582   }
45583 
45584 #if PERFETTO_DCHECK_IS_ON()
45585   // Either |seq_begin| is == index_.begin() or the item immediately before must
45586   // belong to a different {ProducerID, WriterID} sequence.
45587   if (seq_begin != index_.begin() && seq_begin != index_.end()) {
45588     auto prev_it = seq_begin;
45589     prev_it--;
45590     PERFETTO_DCHECK(
45591         seq_begin == index_.begin() ||
45592         std::tie(prev_it->first.producer_id, prev_it->first.writer_id) <
45593             std::tie(seq_begin->first.producer_id, seq_begin->first.writer_id));
45594   }
45595 #endif
45596 
45597   // Find the first entry that has a greater {ProducerID, WriterID} (or just
45598   // index_.end() if we reached the end).
45599   ChunkMeta::Key key = seq_begin->first;  // Deliberate copy.
45600   key.chunk_id = kMaxChunkID;
45601   iter.seq_end = index_.upper_bound(key);
45602   PERFETTO_DCHECK(iter.seq_begin != iter.seq_end);
45603 
45604   // Now find the first entry between [seq_begin, seq_end) that is
45605   // > last_chunk_id_written_. This is where we the sequence will start (see
45606   // notes about wrapping of IDs in the header).
45607   auto producer_and_writer_id = std::make_pair(key.producer_id, key.writer_id);
45608   PERFETTO_DCHECK(last_chunk_id_written_.count(producer_and_writer_id));
45609   iter.wrapping_id = last_chunk_id_written_[producer_and_writer_id];
45610   key.chunk_id = iter.wrapping_id;
45611   iter.cur = index_.upper_bound(key);
45612   if (iter.cur == iter.seq_end)
45613     iter.cur = iter.seq_begin;
45614   return iter;
45615 }
45616 
MoveNext()45617 void TraceBuffer::SequenceIterator::MoveNext() {
45618   // Stop iterating when we reach the end of the sequence.
45619   // Note: |seq_begin| might be == |seq_end|.
45620   if (cur == seq_end || cur->first.chunk_id == wrapping_id) {
45621     cur = seq_end;
45622     return;
45623   }
45624 
45625   // If the current chunk wasn't completed yet, we shouldn't advance past it as
45626   // it may be rewritten with additional packets.
45627   if (!cur->second.is_complete()) {
45628     cur = seq_end;
45629     return;
45630   }
45631 
45632   ChunkID last_chunk_id = cur->first.chunk_id;
45633   if (++cur == seq_end)
45634     cur = seq_begin;
45635 
45636   // There may be a missing chunk in the sequence of chunks, in which case the
45637   // next chunk's ID won't follow the last one's. If so, skip the rest of the
45638   // sequence. We'll return to it later once the hole is filled.
45639   if (last_chunk_id + 1 != cur->first.chunk_id)
45640     cur = seq_end;
45641 }
45642 
ReadNextTracePacket(TracePacket * packet,PacketSequenceProperties * sequence_properties,bool * previous_packet_on_sequence_dropped)45643 bool TraceBuffer::ReadNextTracePacket(
45644     TracePacket* packet,
45645     PacketSequenceProperties* sequence_properties,
45646     bool* previous_packet_on_sequence_dropped) {
45647   // Note: MoveNext() moves only within the next chunk within the same
45648   // {ProducerID, WriterID} sequence. Here we want to:
45649   // - return the next patched+complete packet in the current sequence, if any.
45650   // - return the first patched+complete packet in the next sequence, if any.
45651   // - return false if none of the above is found.
45652   TRACE_BUFFER_DLOG("ReadNextTracePacket()");
45653 
45654   // Just in case we forget to initialize these below.
45655   *sequence_properties = {0, kInvalidUid, 0};
45656   *previous_packet_on_sequence_dropped = false;
45657 
45658   // At the start of each sequence iteration, we consider the last read packet
45659   // dropped. While iterating over the chunks in the sequence, we update this
45660   // flag based on our knowledge about the last packet that was read from each
45661   // chunk (|last_read_packet_skipped| in ChunkMeta).
45662   bool previous_packet_dropped = true;
45663 
45664 #if PERFETTO_DCHECK_IS_ON()
45665   PERFETTO_DCHECK(!changed_since_last_read_);
45666 #endif
45667   for (;; read_iter_.MoveNext()) {
45668     if (PERFETTO_UNLIKELY(!read_iter_.is_valid())) {
45669       // We ran out of chunks in the current {ProducerID, WriterID} sequence or
45670       // we just reached the index_.end().
45671 
45672       if (PERFETTO_UNLIKELY(read_iter_.seq_end == index_.end()))
45673         return false;
45674 
45675       // We reached the end of sequence, move to the next one.
45676       // Note: ++read_iter_.seq_end might become index_.end(), but
45677       // GetReadIterForSequence() knows how to deal with that.
45678       read_iter_ = GetReadIterForSequence(read_iter_.seq_end);
45679       PERFETTO_DCHECK(read_iter_.is_valid() && read_iter_.cur != index_.end());
45680       previous_packet_dropped = true;
45681     }
45682 
45683     ChunkMeta* chunk_meta = &*read_iter_;
45684 
45685     // If the chunk has holes that are awaiting to be patched out-of-band,
45686     // skip the current sequence and move to the next one.
45687     if (chunk_meta->flags & kChunkNeedsPatching) {
45688       read_iter_.MoveToEnd();
45689       continue;
45690     }
45691 
45692     const ProducerID trusted_producer_id = read_iter_.producer_id();
45693     const WriterID writer_id = read_iter_.writer_id();
45694     const uid_t trusted_uid = chunk_meta->trusted_uid;
45695 
45696     // At this point we have a chunk in |chunk_meta| that has not been fully
45697     // read. We don't know yet whether we have enough data to read the full
45698     // packet (in the case it's fragmented over several chunks) and we are about
45699     // to find that out. Specifically:
45700     // A) If the first fragment is unread and is a fragment continuing from a
45701     //    previous chunk, it means we have missed the previous ChunkID. In
45702     //    fact, if this wasn't the case, a previous call to ReadNext() shouldn't
45703     //    have moved the cursor to this chunk.
45704     // B) Any fragment > 0 && < last is always readable. By definition an inner
45705     //    packet is never fragmented and hence doesn't require neither stitching
45706     //    nor any out-of-band patching. The same applies to the last packet
45707     //    iff it doesn't continue on the next chunk.
45708     // C) If the last packet (which might be also the only packet in the chunk)
45709     //    is a fragment and continues on the next chunk, we peek at the next
45710     //    chunks and, if we have all of them, mark as read and move the cursor.
45711     //
45712     // +---------------+   +-------------------+  +---------------+
45713     // | ChunkID: 1    |   | ChunkID: 2        |  | ChunkID: 3    |
45714     // |---------------+   +-------------------+  +---------------+
45715     // | Packet 1      |   |                   |  | ... Packet 3  |
45716     // | Packet 2      |   | ... Packet 3  ... |  | Packet 4      |
45717     // | Packet 3  ... |   |                   |  | Packet 5 ...  |
45718     // +---------------+   +-------------------+  +---------------+
45719 
45720     PERFETTO_DCHECK(chunk_meta->num_fragments_read <=
45721                     chunk_meta->num_fragments);
45722 
45723     // If we didn't read any packets from this chunk, the last packet was from
45724     // the previous chunk we iterated over; so don't update
45725     // |previous_packet_dropped| in this case.
45726     if (chunk_meta->num_fragments_read > 0)
45727       previous_packet_dropped = chunk_meta->last_read_packet_skipped();
45728 
45729     while (chunk_meta->num_fragments_read < chunk_meta->num_fragments) {
45730       enum { kSkip = 0, kReadOnePacket, kTryReadAhead } action;
45731       if (chunk_meta->num_fragments_read == 0) {
45732         if (chunk_meta->flags & kFirstPacketContinuesFromPrevChunk) {
45733           action = kSkip;  // Case A.
45734         } else if (chunk_meta->num_fragments == 1 &&
45735                    (chunk_meta->flags & kLastPacketContinuesOnNextChunk)) {
45736           action = kTryReadAhead;  // Case C.
45737         } else {
45738           action = kReadOnePacket;  // Case B.
45739         }
45740       } else if (chunk_meta->num_fragments_read <
45741                      chunk_meta->num_fragments - 1 ||
45742                  !(chunk_meta->flags & kLastPacketContinuesOnNextChunk)) {
45743         action = kReadOnePacket;  // Case B.
45744       } else {
45745         action = kTryReadAhead;  // Case C.
45746       }
45747 
45748       TRACE_BUFFER_DLOG("  chunk %u, packet %hu of %hu, action=%d",
45749                         read_iter_.chunk_id(), chunk_meta->num_fragments_read,
45750                         chunk_meta->num_fragments, action);
45751 
45752       if (action == kSkip) {
45753         // This fragment will be skipped forever, not just in this ReadPacket()
45754         // iteration. This happens by virtue of ReadNextPacketInChunk()
45755         // incrementing the |num_fragments_read| and marking the fragment as
45756         // read even if we didn't really.
45757         ReadNextPacketInChunk(chunk_meta, nullptr);
45758         chunk_meta->set_last_read_packet_skipped(true);
45759         previous_packet_dropped = true;
45760         continue;
45761       }
45762 
45763       if (action == kReadOnePacket) {
45764         // The easy peasy case B.
45765         ReadPacketResult result = ReadNextPacketInChunk(chunk_meta, packet);
45766 
45767         if (PERFETTO_LIKELY(result == ReadPacketResult::kSucceeded)) {
45768           *sequence_properties = {trusted_producer_id, trusted_uid, writer_id};
45769           *previous_packet_on_sequence_dropped = previous_packet_dropped;
45770           return true;
45771         } else if (result == ReadPacketResult::kFailedEmptyPacket) {
45772           // We can ignore and skip empty packets.
45773           PERFETTO_DCHECK(packet->slices().empty());
45774           continue;
45775         }
45776 
45777         // In extremely rare cases (producer bugged / malicious) the chunk might
45778         // contain an invalid fragment. In such case we don't want to stall the
45779         // sequence but just skip the chunk and move on. ReadNextPacketInChunk()
45780         // marks the chunk as fully read, so we don't attempt to read from it
45781         // again in a future call to ReadBuffers(). It also already records an
45782         // abi violation for this.
45783         PERFETTO_DCHECK(result == ReadPacketResult::kFailedInvalidPacket);
45784         chunk_meta->set_last_read_packet_skipped(true);
45785         previous_packet_dropped = true;
45786         break;
45787       }
45788 
45789       PERFETTO_DCHECK(action == kTryReadAhead);
45790       ReadAheadResult ra_res = ReadAhead(packet);
45791       if (ra_res == ReadAheadResult::kSucceededReturnSlices) {
45792         stats_.set_readaheads_succeeded(stats_.readaheads_succeeded() + 1);
45793         *sequence_properties = {trusted_producer_id, trusted_uid, writer_id};
45794         *previous_packet_on_sequence_dropped = previous_packet_dropped;
45795         return true;
45796       }
45797 
45798       if (ra_res == ReadAheadResult::kFailedMoveToNextSequence) {
45799         // readahead didn't find a contiguous packet sequence. We'll try again
45800         // on the next ReadPacket() call.
45801         stats_.set_readaheads_failed(stats_.readaheads_failed() + 1);
45802 
45803         // TODO(primiano): optimization: this MoveToEnd() is the reason why
45804         // MoveNext() (that is called in the outer for(;;MoveNext)) needs to
45805         // deal gracefully with the case of |cur|==|seq_end|. Maybe we can do
45806         // something to avoid that check by reshuffling the code here?
45807         read_iter_.MoveToEnd();
45808 
45809         // This break will go back to beginning of the for(;;MoveNext()). That
45810         // will move to the next sequence because we set the read iterator to
45811         // its end.
45812         break;
45813       }
45814 
45815       PERFETTO_DCHECK(ra_res == ReadAheadResult::kFailedStayOnSameSequence);
45816 
45817       // In this case ReadAhead() might advance |read_iter_|, so we need to
45818       // re-cache the |chunk_meta| pointer to point to the current chunk.
45819       chunk_meta = &*read_iter_;
45820       chunk_meta->set_last_read_packet_skipped(true);
45821       previous_packet_dropped = true;
45822     }  // while(...)  [iterate over packet fragments for the current chunk].
45823   }    // for(;;MoveNext()) [iterate over chunks].
45824 }
45825 
ReadAhead(TracePacket * packet)45826 TraceBuffer::ReadAheadResult TraceBuffer::ReadAhead(TracePacket* packet) {
45827   static_assert(static_cast<ChunkID>(kMaxChunkID + 1) == 0,
45828                 "relying on kMaxChunkID to wrap naturally");
45829   TRACE_BUFFER_DLOG(" readahead start @ chunk %u", read_iter_.chunk_id());
45830   ChunkID next_chunk_id = read_iter_.chunk_id() + 1;
45831   SequenceIterator it = read_iter_;
45832   for (it.MoveNext(); it.is_valid(); it.MoveNext(), next_chunk_id++) {
45833     // We should stay within the same sequence while iterating here.
45834     PERFETTO_DCHECK(it.producer_id() == read_iter_.producer_id() &&
45835                     it.writer_id() == read_iter_.writer_id());
45836 
45837     TRACE_BUFFER_DLOG("   expected chunk ID: %u, actual ID: %u", next_chunk_id,
45838                       it.chunk_id());
45839 
45840     if (PERFETTO_UNLIKELY((*it).num_fragments == 0))
45841       continue;
45842 
45843     // If we miss the next chunk, stop looking in the current sequence and
45844     // try another sequence. This chunk might come in the near future.
45845     // The second condition is the edge case of a buggy/malicious
45846     // producer. The ChunkID is contiguous but its flags don't make sense.
45847     if (it.chunk_id() != next_chunk_id ||
45848         PERFETTO_UNLIKELY(
45849             !((*it).flags & kFirstPacketContinuesFromPrevChunk))) {
45850       return ReadAheadResult::kFailedMoveToNextSequence;
45851     }
45852 
45853     // If the chunk is contiguous but has not been patched yet move to the next
45854     // sequence and try coming back here on the next ReadNextTracePacket() call.
45855     // TODO(primiano): add a test to cover this, it's a subtle case.
45856     if ((*it).flags & kChunkNeedsPatching)
45857       return ReadAheadResult::kFailedMoveToNextSequence;
45858 
45859     // This is the case of an intermediate chunk which contains only one
45860     // fragment which continues on the next chunk. This is the case for large
45861     // packets, e.g.: [Packet0, Packet1(0)] [Packet1(1)] [Packet1(2), ...]
45862     // (Packet1(X) := fragment X of Packet1).
45863     if ((*it).num_fragments == 1 &&
45864         ((*it).flags & kLastPacketContinuesOnNextChunk)) {
45865       continue;
45866     }
45867 
45868     // We made it! We got all fragments for the packet without holes.
45869     TRACE_BUFFER_DLOG("  readahead success @ chunk %u", it.chunk_id());
45870     PERFETTO_DCHECK(((*it).num_fragments == 1 &&
45871                      !((*it).flags & kLastPacketContinuesOnNextChunk)) ||
45872                     (*it).num_fragments > 1);
45873 
45874     // Now let's re-iterate over the [read_iter_, it] sequence and mark
45875     // all the fragments as read.
45876     bool packet_corruption = false;
45877     for (;;) {
45878       PERFETTO_DCHECK(read_iter_.is_valid());
45879       TRACE_BUFFER_DLOG("    commit chunk %u", read_iter_.chunk_id());
45880       if (PERFETTO_LIKELY((*read_iter_).num_fragments > 0)) {
45881         // In the unlikely case of a corrupted packet (corrupted or empty
45882         // fragment), invalidate the all stitching and move on to the next chunk
45883         // in the same sequence, if any.
45884         packet_corruption |= ReadNextPacketInChunk(&*read_iter_, packet) ==
45885                              ReadPacketResult::kFailedInvalidPacket;
45886       }
45887       if (read_iter_.cur == it.cur)
45888         break;
45889       read_iter_.MoveNext();
45890     }  // for(;;)
45891     PERFETTO_DCHECK(read_iter_.cur == it.cur);
45892 
45893     if (PERFETTO_UNLIKELY(packet_corruption)) {
45894       // ReadNextPacketInChunk() already records an abi violation for this case.
45895       *packet = TracePacket();  // clear.
45896       return ReadAheadResult::kFailedStayOnSameSequence;
45897     }
45898 
45899     return ReadAheadResult::kSucceededReturnSlices;
45900   }  // for(it...)  [readahead loop]
45901   return ReadAheadResult::kFailedMoveToNextSequence;
45902 }
45903 
ReadNextPacketInChunk(ChunkMeta * chunk_meta,TracePacket * packet)45904 TraceBuffer::ReadPacketResult TraceBuffer::ReadNextPacketInChunk(
45905     ChunkMeta* chunk_meta,
45906     TracePacket* packet) {
45907   PERFETTO_DCHECK(chunk_meta->num_fragments_read < chunk_meta->num_fragments);
45908   PERFETTO_DCHECK(!(chunk_meta->flags & kChunkNeedsPatching));
45909 
45910   const uint8_t* record_begin =
45911       reinterpret_cast<const uint8_t*>(chunk_meta->chunk_record);
45912   const uint8_t* record_end = record_begin + chunk_meta->chunk_record->size;
45913   const uint8_t* packets_begin = record_begin + sizeof(ChunkRecord);
45914   const uint8_t* packet_begin = packets_begin + chunk_meta->cur_fragment_offset;
45915 
45916   if (PERFETTO_UNLIKELY(packet_begin < packets_begin ||
45917                         packet_begin >= record_end)) {
45918     // The producer has a bug or is malicious and did declare that the chunk
45919     // contains more packets beyond its boundaries.
45920     stats_.set_abi_violations(stats_.abi_violations() + 1);
45921     PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
45922     chunk_meta->cur_fragment_offset = 0;
45923     chunk_meta->num_fragments_read = chunk_meta->num_fragments;
45924     if (PERFETTO_LIKELY(chunk_meta->is_complete())) {
45925       stats_.set_chunks_read(stats_.chunks_read() + 1);
45926       stats_.set_bytes_read(stats_.bytes_read() +
45927                             chunk_meta->chunk_record->size);
45928     }
45929     return ReadPacketResult::kFailedInvalidPacket;
45930   }
45931 
45932   // A packet (or a fragment) starts with a varint stating its size, followed
45933   // by its content. The varint shouldn't be larger than 4 bytes (just in case
45934   // the producer is using a redundant encoding)
45935   uint64_t packet_size = 0;
45936   const uint8_t* header_end =
45937       std::min(packet_begin + protozero::proto_utils::kMessageLengthFieldSize,
45938                record_end);
45939   const uint8_t* packet_data = protozero::proto_utils::ParseVarInt(
45940       packet_begin, header_end, &packet_size);
45941 
45942   const uint8_t* next_packet = packet_data + packet_size;
45943   if (PERFETTO_UNLIKELY(next_packet <= packet_begin ||
45944                         next_packet > record_end)) {
45945     // In BufferExhaustedPolicy::kDrop mode, TraceWriter may abort a fragmented
45946     // packet by writing an invalid size in the last fragment's header. We
45947     // should handle this case without recording an ABI violation (since Android
45948     // R).
45949     if (packet_size != SharedMemoryABI::kPacketSizeDropPacket) {
45950       stats_.set_abi_violations(stats_.abi_violations() + 1);
45951       PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
45952     } else {
45953       stats_.set_trace_writer_packet_loss(stats_.trace_writer_packet_loss() +
45954                                           1);
45955     }
45956     chunk_meta->cur_fragment_offset = 0;
45957     chunk_meta->num_fragments_read = chunk_meta->num_fragments;
45958     if (PERFETTO_LIKELY(chunk_meta->is_complete())) {
45959       stats_.set_chunks_read(stats_.chunks_read() + 1);
45960       stats_.set_bytes_read(stats_.bytes_read() +
45961                             chunk_meta->chunk_record->size);
45962     }
45963     return ReadPacketResult::kFailedInvalidPacket;
45964   }
45965 
45966   chunk_meta->cur_fragment_offset =
45967       static_cast<uint16_t>(next_packet - packets_begin);
45968   chunk_meta->num_fragments_read++;
45969 
45970   if (PERFETTO_UNLIKELY(chunk_meta->num_fragments_read ==
45971                             chunk_meta->num_fragments &&
45972                         chunk_meta->is_complete())) {
45973     stats_.set_chunks_read(stats_.chunks_read() + 1);
45974     stats_.set_bytes_read(stats_.bytes_read() + chunk_meta->chunk_record->size);
45975   } else {
45976     // We have at least one more packet to parse. It should be within the chunk.
45977     if (chunk_meta->cur_fragment_offset + sizeof(ChunkRecord) >=
45978         chunk_meta->chunk_record->size) {
45979       PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
45980     }
45981   }
45982 
45983   chunk_meta->set_last_read_packet_skipped(false);
45984 
45985   if (PERFETTO_UNLIKELY(packet_size == 0))
45986     return ReadPacketResult::kFailedEmptyPacket;
45987 
45988   if (PERFETTO_LIKELY(packet))
45989     packet->AddSlice(packet_data, static_cast<size_t>(packet_size));
45990 
45991   return ReadPacketResult::kSucceeded;
45992 }
45993 
DiscardWrite()45994 void TraceBuffer::DiscardWrite() {
45995   PERFETTO_DCHECK(overwrite_policy_ == kDiscard);
45996   discard_writes_ = true;
45997   stats_.set_chunks_discarded(stats_.chunks_discarded() + 1);
45998   TRACE_BUFFER_DLOG("  discarding write");
45999 }
46000 
46001 }  // namespace perfetto
46002 // gen_amalgamated begin source: src/tracing/core/tracing_service_impl.cc
46003 // gen_amalgamated begin header: src/tracing/core/tracing_service_impl.h
46004 // gen_amalgamated begin header: include/perfetto/ext/base/circular_queue.h
46005 /*
46006  * Copyright (C) 2019 The Android Open Source Project
46007  *
46008  * Licensed under the Apache License, Version 2.0 (the "License");
46009  * you may not use this file except in compliance with the License.
46010  * You may obtain a copy of the License at
46011  *
46012  *      http://www.apache.org/licenses/LICENSE-2.0
46013  *
46014  * Unless required by applicable law or agreed to in writing, software
46015  * distributed under the License is distributed on an "AS IS" BASIS,
46016  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
46017  * See the License for the specific language governing permissions and
46018  * limitations under the License.
46019  */
46020 
46021 #ifndef INCLUDE_PERFETTO_EXT_BASE_CIRCULAR_QUEUE_H_
46022 #define INCLUDE_PERFETTO_EXT_BASE_CIRCULAR_QUEUE_H_
46023 
46024 #include <stdint.h>
46025 #include <iterator>
46026 
46027 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
46028 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
46029 
46030 namespace perfetto {
46031 namespace base {
46032 
46033 // CircularQueue is a push-back-only / pop-front-only queue with the following
46034 // characteristics:
46035 // - The storage is based on a flat circular buffer. Beginning and end wrap
46036 //   as necessary, to keep pushes and pops O(1) as long as capacity expansion is
46037 //   not required.
46038 // - Capacity is automatically expanded like in a std::vector. Expansion has a
46039 //   O(N) cost.
46040 // - It allows random access, allowing in-place std::sort.
46041 // - Iterators are not stable. Mutating the container invalidates all iterators.
46042 // - It doesn't bother with const-correctness.
46043 //
46044 // Implementation details:
46045 // Internally, |begin|, |end| and iterators use 64-bit monotonic indexes, which
46046 // are incremented as if the queue was backed by unlimited storage.
46047 // Even assuming that elements are inserted and removed every nanosecond, 64 bit
46048 // is enough for 584 years.
46049 // Wrapping happens only when addressing elements in the underlying circular
46050 // storage. This limits the complexity and avoiding dealing with modular
46051 // arithmetic all over the places.
46052 template <class T>
46053 class CircularQueue {
46054  public:
46055   class Iterator {
46056    public:
46057     using difference_type = ptrdiff_t;
46058     using value_type = T;
46059     using pointer = T*;
46060     using reference = T&;
46061     using iterator_category = std::random_access_iterator_tag;
46062 
Iterator(CircularQueue * queue,uint64_t pos,uint32_t generation)46063     Iterator(CircularQueue* queue, uint64_t pos, uint32_t generation)
46064         : queue_(queue),
46065           pos_(pos)
46066 #if PERFETTO_DCHECK_IS_ON()
46067           ,
46068           generation_(generation)
46069 #endif
46070     {
46071       ignore_result(generation);
46072     }
46073 
46074     Iterator(const Iterator&) noexcept = default;
46075     Iterator& operator=(const Iterator&) noexcept = default;
46076     Iterator(Iterator&&) noexcept = default;
46077     Iterator& operator=(Iterator&&) noexcept = default;
46078 
operator ->() const46079     T* operator->() const {
46080 #if PERFETTO_DCHECK_IS_ON()
46081       PERFETTO_DCHECK(generation_ == queue_->generation());
46082 #endif
46083       return queue_->Get(pos_);
46084     }
46085 
operator *() const46086     T& operator*() const { return *(operator->()); }
46087 
operator [](difference_type i)46088     value_type& operator[](difference_type i) { return *(*this + i); }
46089 
operator ++()46090     Iterator& operator++() {
46091       Add(1);
46092       return *this;
46093     }
46094 
operator ++(int)46095     Iterator operator++(int) {
46096       Iterator ret = *this;
46097       Add(1);
46098       return ret;
46099     }
46100 
operator --()46101     Iterator& operator--() {
46102       Add(-1);
46103       return *this;
46104     }
46105 
operator --(int)46106     Iterator operator--(int) {
46107       Iterator ret = *this;
46108       Add(-1);
46109       return ret;
46110     }
46111 
operator +(const Iterator & iter,difference_type offset)46112     friend Iterator operator+(const Iterator& iter, difference_type offset) {
46113       Iterator ret = iter;
46114       ret.Add(offset);
46115       return ret;
46116     }
46117 
operator +=(difference_type offset)46118     Iterator& operator+=(difference_type offset) {
46119       Add(offset);
46120       return *this;
46121     }
46122 
operator -(const Iterator & iter,difference_type offset)46123     friend Iterator operator-(const Iterator& iter, difference_type offset) {
46124       Iterator ret = iter;
46125       ret.Add(-offset);
46126       return ret;
46127     }
46128 
operator -=(difference_type offset)46129     Iterator& operator-=(difference_type offset) {
46130       Add(-offset);
46131       return *this;
46132     }
46133 
operator -(const Iterator & lhs,const Iterator & rhs)46134     friend ptrdiff_t operator-(const Iterator& lhs, const Iterator& rhs) {
46135       return static_cast<ptrdiff_t>(lhs.pos_) -
46136              static_cast<ptrdiff_t>(rhs.pos_);
46137     }
46138 
operator ==(const Iterator & lhs,const Iterator & rhs)46139     friend bool operator==(const Iterator& lhs, const Iterator& rhs) {
46140       return lhs.pos_ == rhs.pos_;
46141     }
46142 
operator !=(const Iterator & lhs,const Iterator & rhs)46143     friend bool operator!=(const Iterator& lhs, const Iterator& rhs) {
46144       return lhs.pos_ != rhs.pos_;
46145     }
46146 
operator <(const Iterator & lhs,const Iterator & rhs)46147     friend bool operator<(const Iterator& lhs, const Iterator& rhs) {
46148       return lhs.pos_ < rhs.pos_;
46149     }
46150 
operator <=(const Iterator & lhs,const Iterator & rhs)46151     friend bool operator<=(const Iterator& lhs, const Iterator& rhs) {
46152       return lhs.pos_ <= rhs.pos_;
46153     }
46154 
operator >(const Iterator & lhs,const Iterator & rhs)46155     friend bool operator>(const Iterator& lhs, const Iterator& rhs) {
46156       return lhs.pos_ > rhs.pos_;
46157     }
46158 
operator >=(const Iterator & lhs,const Iterator & rhs)46159     friend bool operator>=(const Iterator& lhs, const Iterator& rhs) {
46160       return lhs.pos_ >= rhs.pos_;
46161     }
46162 
46163    private:
Add(difference_type offset)46164     inline void Add(difference_type offset) {
46165       pos_ = static_cast<uint64_t>(static_cast<difference_type>(pos_) + offset);
46166       PERFETTO_DCHECK(pos_ <= queue_->end_);
46167     }
46168 
46169     CircularQueue* queue_;
46170     uint64_t pos_;
46171 
46172 #if PERFETTO_DCHECK_IS_ON()
46173     uint32_t generation_;
46174 #endif
46175   };
46176 
CircularQueue(size_t initial_capacity=1024)46177   CircularQueue(size_t initial_capacity = 1024) { Grow(initial_capacity); }
46178 
CircularQueue(CircularQueue && other)46179   CircularQueue(CircularQueue&& other) noexcept {
46180     // Copy all fields using the (private) default copy assignment operator.
46181     *this = other;
46182     increment_generation();
46183     new (&other) CircularQueue();  // Reset the old queue so it's still usable.
46184   }
46185 
operator =(CircularQueue && other)46186   CircularQueue& operator=(CircularQueue&& other) {
46187     this->~CircularQueue();                      // Destroy the current state.
46188     new (this) CircularQueue(std::move(other));  // Use the move ctor above.
46189     return *this;
46190   }
46191 
~CircularQueue()46192   ~CircularQueue() {
46193     if (!entries_) {
46194       PERFETTO_DCHECK(empty());
46195       return;
46196     }
46197     clear();  // Invoke destructors on all alive entries.
46198     PERFETTO_DCHECK(empty());
46199     free(entries_);
46200   }
46201 
46202   template <typename... Args>
emplace_back(Args &&...args)46203   void emplace_back(Args&&... args) {
46204     increment_generation();
46205     if (PERFETTO_UNLIKELY(size() >= capacity_))
46206       Grow();
46207     T* slot = Get(end_++);
46208     new (slot) T(std::forward<Args>(args)...);
46209   }
46210 
erase_front(size_t n)46211   void erase_front(size_t n) {
46212     increment_generation();
46213     for (; n && (begin_ < end_); --n) {
46214       Get(begin_)->~T();
46215       begin_++;  // This needs to be its own statement, Get() checks begin_.
46216     }
46217   }
46218 
pop_front()46219   void pop_front() { erase_front(1); }
46220 
clear()46221   void clear() { erase_front(size()); }
46222 
at(size_t idx)46223   T& at(size_t idx) {
46224     PERFETTO_DCHECK(idx < size());
46225     return *Get(begin_ + idx);
46226   }
46227 
begin()46228   Iterator begin() { return Iterator(this, begin_, generation()); }
end()46229   Iterator end() { return Iterator(this, end_, generation()); }
front()46230   T& front() { return *begin(); }
back()46231   T& back() { return *(end() - 1); }
46232 
empty() const46233   bool empty() const { return size() == 0; }
46234 
size() const46235   size_t size() const {
46236     PERFETTO_DCHECK(end_ - begin_ <= capacity_);
46237     return static_cast<size_t>(end_ - begin_);
46238   }
46239 
capacity() const46240   size_t capacity() const { return capacity_; }
46241 
46242 #if PERFETTO_DCHECK_IS_ON()
generation() const46243   uint32_t generation() const { return generation_; }
increment_generation()46244   void increment_generation() { ++generation_; }
46245 #else
generation() const46246   uint32_t generation() const { return 0; }
increment_generation()46247   void increment_generation() {}
46248 #endif
46249 
46250  private:
46251   CircularQueue(const CircularQueue&) = delete;
46252   CircularQueue& operator=(const CircularQueue&) = default;
46253 
Grow(size_t new_capacity=0)46254   void Grow(size_t new_capacity = 0) {
46255     // Capacity must be always a power of two. This allows Get() to use a simple
46256     // bitwise-AND for handling the wrapping instead of a full division.
46257     new_capacity = new_capacity ? new_capacity : capacity_ * 2;
46258     PERFETTO_CHECK((new_capacity & (new_capacity - 1)) == 0);  // Must be pow2.
46259 
46260     // On 32-bit systems this might hit the 4GB wall and overflow. We can't do
46261     // anything other than crash in this case.
46262     PERFETTO_CHECK(new_capacity > capacity_);
46263     size_t malloc_size = new_capacity * sizeof(T);
46264     PERFETTO_CHECK(malloc_size > new_capacity);
46265     auto* new_vec = static_cast<T*>(malloc(malloc_size));
46266 
46267     // Move all elements in the expanded array.
46268     size_t new_size = 0;
46269     for (uint64_t i = begin_; i < end_; i++)
46270       new (&new_vec[new_size++]) T(std::move(*Get(i)));  // Placement move ctor.
46271 
46272     // Even if all the elements are std::move()-d and likely empty, we are still
46273     // required to call the dtor for them.
46274     for (uint64_t i = begin_; i < end_; i++)
46275       Get(i)->~T();
46276     free(entries_);  // It's fine to free(nullptr) (for the ctor call case).
46277 
46278     begin_ = 0;
46279     end_ = new_size;
46280     capacity_ = new_capacity;
46281     entries_ = new_vec;
46282   }
46283 
Get(uint64_t pos)46284   inline T* Get(uint64_t pos) {
46285     PERFETTO_DCHECK(pos >= begin_ && pos < end_);
46286     PERFETTO_DCHECK((capacity_ & (capacity_ - 1)) == 0);  // Must be a pow2.
46287     auto index = static_cast<size_t>(pos & (capacity_ - 1));
46288     return &entries_[index];
46289   }
46290 
46291   // Underlying storage. It's raw malloc-ed rather than being a unique_ptr<T[]>
46292   // to allow having uninitialized entries inside it.
46293   T* entries_ = nullptr;
46294   size_t capacity_ = 0;  // Number of allocated slots (NOT bytes) in |entries_|.
46295 
46296   // The |begin_| and |end_| indexes are monotonic and never wrap. Modular arith
46297   // is used only when dereferencing entries in the vector.
46298   uint64_t begin_ = 0;
46299   uint64_t end_ = 0;
46300 
46301 // Generation is used in debug builds only for checking iterator validity.
46302 #if PERFETTO_DCHECK_IS_ON()
46303   uint32_t generation_ = 0;
46304 #endif
46305 };
46306 
46307 }  // namespace base
46308 }  // namespace perfetto
46309 
46310 #endif  // INCLUDE_PERFETTO_EXT_BASE_CIRCULAR_QUEUE_H_
46311 /*
46312  * Copyright (C) 2017 The Android Open Source Project
46313  *
46314  * Licensed under the Apache License, Version 2.0 (the "License");
46315  * you may not use this file except in compliance with the License.
46316  * You may obtain a copy of the License at
46317  *
46318  *      http://www.apache.org/licenses/LICENSE-2.0
46319  *
46320  * Unless required by applicable law or agreed to in writing, software
46321  * distributed under the License is distributed on an "AS IS" BASIS,
46322  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
46323  * See the License for the specific language governing permissions and
46324  * limitations under the License.
46325  */
46326 
46327 #ifndef SRC_TRACING_CORE_TRACING_SERVICE_IMPL_H_
46328 #define SRC_TRACING_CORE_TRACING_SERVICE_IMPL_H_
46329 
46330 #include <algorithm>
46331 #include <functional>
46332 #include <map>
46333 #include <memory>
46334 #include <mutex>
46335 #include <random>
46336 #include <set>
46337 #include <utility>
46338 #include <vector>
46339 
46340 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
46341 // gen_amalgamated expanded: #include "perfetto/base/status.h"
46342 // gen_amalgamated expanded: #include "perfetto/base/time.h"
46343 // gen_amalgamated expanded: #include "perfetto/ext/base/circular_queue.h"
46344 // gen_amalgamated expanded: #include "perfetto/ext/base/optional.h"
46345 // gen_amalgamated expanded: #include "perfetto/ext/base/periodic_task.h"
46346 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
46347 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
46348 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/commit_data_request.h"
46349 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/observable_events.h"
46350 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
46351 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_stats.h"
46352 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
46353 // gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
46354 // gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
46355 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
46356 // gen_amalgamated expanded: #include "perfetto/tracing/core/trace_config.h"
46357 // gen_amalgamated expanded: #include "src/android_stats/perfetto_atoms.h"
46358 // gen_amalgamated expanded: #include "src/tracing/core/id_allocator.h"
46359 
46360 namespace protozero {
46361 class MessageFilter;
46362 }
46363 
46364 namespace perfetto {
46365 
46366 namespace base {
46367 class TaskRunner;
46368 }  // namespace base
46369 
46370 class Consumer;
46371 class Producer;
46372 class SharedMemory;
46373 class SharedMemoryArbiterImpl;
46374 class TraceBuffer;
46375 class TracePacket;
46376 
46377 // The tracing service business logic.
46378 class TracingServiceImpl : public TracingService {
46379  private:
46380   struct DataSourceInstance;
46381 
46382  public:
46383   static constexpr size_t kDefaultShmPageSize = 4096ul;
46384   static constexpr size_t kDefaultShmSize = 256 * 1024ul;
46385   static constexpr size_t kMaxShmSize = 32 * 1024 * 1024ul;
46386   static constexpr uint32_t kDataSourceStopTimeoutMs = 5000;
46387   static constexpr uint8_t kSyncMarker[] = {0x82, 0x47, 0x7a, 0x76, 0xb2, 0x8d,
46388                                             0x42, 0xba, 0x81, 0xdc, 0x33, 0x32,
46389                                             0x6d, 0x57, 0xa0, 0x79};
46390 
46391   // The implementation behind the service endpoint exposed to each producer.
46392   class ProducerEndpointImpl : public TracingService::ProducerEndpoint {
46393    public:
46394     ProducerEndpointImpl(ProducerID,
46395                          uid_t uid,
46396                          TracingServiceImpl*,
46397                          base::TaskRunner*,
46398                          Producer*,
46399                          const std::string& producer_name,
46400                          const std::string& sdk_version,
46401                          bool in_process,
46402                          bool smb_scraping_enabled);
46403     ~ProducerEndpointImpl() override;
46404 
46405     // TracingService::ProducerEndpoint implementation.
46406     void RegisterDataSource(const DataSourceDescriptor&) override;
46407     void UnregisterDataSource(const std::string& name) override;
46408     void RegisterTraceWriter(uint32_t writer_id,
46409                              uint32_t target_buffer) override;
46410     void UnregisterTraceWriter(uint32_t writer_id) override;
46411     void CommitData(const CommitDataRequest&, CommitDataCallback) override;
46412     void SetupSharedMemory(std::unique_ptr<SharedMemory>,
46413                            size_t page_size_bytes,
46414                            bool provided_by_producer);
46415     std::unique_ptr<TraceWriter> CreateTraceWriter(
46416         BufferID,
46417         BufferExhaustedPolicy) override;
46418     SharedMemoryArbiter* MaybeSharedMemoryArbiter() override;
46419     bool IsShmemProvidedByProducer() const override;
46420     void NotifyFlushComplete(FlushRequestID) override;
46421     void NotifyDataSourceStarted(DataSourceInstanceID) override;
46422     void NotifyDataSourceStopped(DataSourceInstanceID) override;
46423     SharedMemory* shared_memory() const override;
46424     size_t shared_buffer_page_size_kb() const override;
46425     void ActivateTriggers(const std::vector<std::string>&) override;
46426     void Sync(std::function<void()> callback) override;
46427 
46428     void OnTracingSetup();
46429     void SetupDataSource(DataSourceInstanceID, const DataSourceConfig&);
46430     void StartDataSource(DataSourceInstanceID, const DataSourceConfig&);
46431     void StopDataSource(DataSourceInstanceID);
46432     void Flush(FlushRequestID, const std::vector<DataSourceInstanceID>&);
46433     void OnFreeBuffers(const std::vector<BufferID>& target_buffers);
46434     void ClearIncrementalState(const std::vector<DataSourceInstanceID>&);
46435 
is_allowed_target_buffer(BufferID buffer_id) const46436     bool is_allowed_target_buffer(BufferID buffer_id) const {
46437       return allowed_target_buffers_.count(buffer_id);
46438     }
46439 
buffer_id_for_writer(WriterID writer_id) const46440     base::Optional<BufferID> buffer_id_for_writer(WriterID writer_id) const {
46441       const auto it = writers_.find(writer_id);
46442       if (it != writers_.end())
46443         return it->second;
46444       return base::nullopt;
46445     }
46446 
uid() const46447     uid_t uid() const { return uid_; }
46448 
46449    private:
46450     friend class TracingServiceImpl;
46451     friend class TracingServiceImplTest;
46452     friend class TracingIntegrationTest;
46453     ProducerEndpointImpl(const ProducerEndpointImpl&) = delete;
46454     ProducerEndpointImpl& operator=(const ProducerEndpointImpl&) = delete;
46455 
46456     ProducerID const id_;
46457     const uid_t uid_;
46458     TracingServiceImpl* const service_;
46459     base::TaskRunner* const task_runner_;
46460     Producer* producer_;
46461     std::unique_ptr<SharedMemory> shared_memory_;
46462     size_t shared_buffer_page_size_kb_ = 0;
46463     SharedMemoryABI shmem_abi_;
46464     size_t shmem_size_hint_bytes_ = 0;
46465     size_t shmem_page_size_hint_bytes_ = 0;
46466     bool is_shmem_provided_by_producer_ = false;
46467     const std::string name_;
46468     std::string sdk_version_;
46469     bool in_process_;
46470     bool smb_scraping_enabled_;
46471 
46472     // Set of the global target_buffer IDs that the producer is configured to
46473     // write into in any active tracing session.
46474     std::set<BufferID> allowed_target_buffers_;
46475 
46476     // Maps registered TraceWriter IDs to their target buffers as registered by
46477     // the producer. Note that producers aren't required to register their
46478     // writers, so we may see commits of chunks with WriterIDs that aren't
46479     // contained in this map. However, if a producer does register a writer, the
46480     // service will prevent the writer from writing into any other buffer than
46481     // the one associated with it here. The BufferIDs stored in this map are
46482     // untrusted, so need to be verified against |allowed_target_buffers_|
46483     // before use.
46484     std::map<WriterID, BufferID> writers_;
46485 
46486     // This is used only in in-process configurations.
46487     // SharedMemoryArbiterImpl methods themselves are thread-safe.
46488     std::unique_ptr<SharedMemoryArbiterImpl> inproc_shmem_arbiter_;
46489 
46490     PERFETTO_THREAD_CHECKER(thread_checker_)
46491     base::WeakPtrFactory<ProducerEndpointImpl> weak_ptr_factory_;  // Keep last.
46492   };
46493 
46494   // The implementation behind the service endpoint exposed to each consumer.
46495   class ConsumerEndpointImpl : public TracingService::ConsumerEndpoint {
46496    public:
46497     ConsumerEndpointImpl(TracingServiceImpl*,
46498                          base::TaskRunner*,
46499                          Consumer*,
46500                          uid_t uid);
46501     ~ConsumerEndpointImpl() override;
46502 
46503     void NotifyOnTracingDisabled(const std::string& error);
46504 
46505     // TracingService::ConsumerEndpoint implementation.
46506     void EnableTracing(const TraceConfig&, base::ScopedFile) override;
46507     void ChangeTraceConfig(const TraceConfig& cfg) override;
46508     void StartTracing() override;
46509     void DisableTracing() override;
46510     void ReadBuffers() override;
46511     void FreeBuffers() override;
46512     void Flush(uint32_t timeout_ms, FlushCallback) override;
46513     void Detach(const std::string& key) override;
46514     void Attach(const std::string& key) override;
46515     void GetTraceStats() override;
46516     void ObserveEvents(uint32_t enabled_event_types) override;
46517     void QueryServiceState(QueryServiceStateCallback) override;
46518     void QueryCapabilities(QueryCapabilitiesCallback) override;
46519     void SaveTraceForBugreport(SaveTraceForBugreportCallback) override;
46520 
46521     // Will queue a task to notify the consumer about the state change.
46522     void OnDataSourceInstanceStateChange(const ProducerEndpointImpl&,
46523                                          const DataSourceInstance&);
46524     void OnAllDataSourcesStarted();
46525 
46526    private:
46527     friend class TracingServiceImpl;
46528     ConsumerEndpointImpl(const ConsumerEndpointImpl&) = delete;
46529     ConsumerEndpointImpl& operator=(const ConsumerEndpointImpl&) = delete;
46530 
46531     // Returns a pointer to an ObservableEvents object that the caller can fill
46532     // and schedules a task to send the ObservableEvents to the consumer.
46533     ObservableEvents* AddObservableEvents();
46534 
46535     base::TaskRunner* const task_runner_;
46536     TracingServiceImpl* const service_;
46537     Consumer* const consumer_;
46538     uid_t const uid_;
46539     TracingSessionID tracing_session_id_ = 0;
46540 
46541     // Whether the consumer is interested in DataSourceInstance state change
46542     // events.
46543     uint32_t observable_events_mask_ = 0;
46544 
46545     // ObservableEvents that will be sent to the consumer. If set, a task to
46546     // flush the events to the consumer has been queued.
46547     std::unique_ptr<ObservableEvents> observable_events_;
46548 
46549     PERFETTO_THREAD_CHECKER(thread_checker_)
46550     base::WeakPtrFactory<ConsumerEndpointImpl> weak_ptr_factory_;  // Keep last.
46551   };
46552 
46553   explicit TracingServiceImpl(std::unique_ptr<SharedMemory::Factory>,
46554                               base::TaskRunner*);
46555   ~TracingServiceImpl() override;
46556 
46557   // Called by ProducerEndpointImpl.
46558   void DisconnectProducer(ProducerID);
46559   void RegisterDataSource(ProducerID, const DataSourceDescriptor&);
46560   void UnregisterDataSource(ProducerID, const std::string& name);
46561   void CopyProducerPageIntoLogBuffer(ProducerID,
46562                                      uid_t,
46563                                      WriterID,
46564                                      ChunkID,
46565                                      BufferID,
46566                                      uint16_t num_fragments,
46567                                      uint8_t chunk_flags,
46568                                      bool chunk_complete,
46569                                      const uint8_t* src,
46570                                      size_t size);
46571   void ApplyChunkPatches(ProducerID,
46572                          const std::vector<CommitDataRequest::ChunkToPatch>&);
46573   void NotifyFlushDoneForProducer(ProducerID, FlushRequestID);
46574   void NotifyDataSourceStarted(ProducerID, const DataSourceInstanceID);
46575   void NotifyDataSourceStopped(ProducerID, const DataSourceInstanceID);
46576   void ActivateTriggers(ProducerID, const std::vector<std::string>& triggers);
46577 
46578   // Called by ConsumerEndpointImpl.
46579   bool DetachConsumer(ConsumerEndpointImpl*, const std::string& key);
46580   bool AttachConsumer(ConsumerEndpointImpl*, const std::string& key);
46581   void DisconnectConsumer(ConsumerEndpointImpl*);
46582   base::Status EnableTracing(ConsumerEndpointImpl*,
46583                              const TraceConfig&,
46584                              base::ScopedFile);
46585   void ChangeTraceConfig(ConsumerEndpointImpl*, const TraceConfig&);
46586 
46587   base::Status StartTracing(TracingSessionID);
46588   void DisableTracing(TracingSessionID, bool disable_immediately = false);
46589   void Flush(TracingSessionID tsid,
46590              uint32_t timeout_ms,
46591              ConsumerEndpoint::FlushCallback);
46592   void FlushAndDisableTracing(TracingSessionID);
46593   bool ReadBuffers(TracingSessionID, ConsumerEndpointImpl*);
46594   void FreeBuffers(TracingSessionID);
46595 
46596   // Service implementation.
46597   std::unique_ptr<TracingService::ProducerEndpoint> ConnectProducer(
46598       Producer*,
46599       uid_t uid,
46600       const std::string& producer_name,
46601       size_t shared_memory_size_hint_bytes = 0,
46602       bool in_process = false,
46603       ProducerSMBScrapingMode smb_scraping_mode =
46604           ProducerSMBScrapingMode::kDefault,
46605       size_t shared_memory_page_size_hint_bytes = 0,
46606       std::unique_ptr<SharedMemory> shm = nullptr,
46607       const std::string& sdk_version = {}) override;
46608 
46609   std::unique_ptr<TracingService::ConsumerEndpoint> ConnectConsumer(
46610       Consumer*,
46611       uid_t) override;
46612 
46613   // Set whether SMB scraping should be enabled by default or not. Producers can
46614   // override this setting for their own SMBs.
SetSMBScrapingEnabled(bool enabled)46615   void SetSMBScrapingEnabled(bool enabled) override {
46616     smb_scraping_enabled_ = enabled;
46617   }
46618 
46619   // Exposed mainly for testing.
num_producers() const46620   size_t num_producers() const { return producers_.size(); }
46621   ProducerEndpointImpl* GetProducer(ProducerID) const;
46622 
46623  private:
46624   friend class TracingServiceImplTest;
46625   friend class TracingIntegrationTest;
46626 
46627   static constexpr int64_t kOneDayInNs = 24ll * 60 * 60 * 1000 * 1000 * 1000;
46628 
46629   struct TriggerHistory {
46630     int64_t timestamp_ns;
46631     uint64_t name_hash;
46632 
operator <perfetto::TracingServiceImpl::TriggerHistory46633     bool operator<(const TriggerHistory& other) const {
46634       return timestamp_ns < other.timestamp_ns;
46635     }
46636   };
46637 
46638   struct RegisteredDataSource {
46639     ProducerID producer_id;
46640     DataSourceDescriptor descriptor;
46641   };
46642 
46643   // Represents an active data source for a tracing session.
46644   struct DataSourceInstance {
DataSourceInstanceperfetto::TracingServiceImpl::DataSourceInstance46645     DataSourceInstance(DataSourceInstanceID id,
46646                        const DataSourceConfig& cfg,
46647                        const std::string& ds_name,
46648                        bool notify_on_start,
46649                        bool notify_on_stop,
46650                        bool handles_incremental_state_invalidation)
46651         : instance_id(id),
46652           config(cfg),
46653           data_source_name(ds_name),
46654           will_notify_on_start(notify_on_start),
46655           will_notify_on_stop(notify_on_stop),
46656           handles_incremental_state_clear(
46657               handles_incremental_state_invalidation) {}
46658     DataSourceInstance(const DataSourceInstance&) = delete;
46659     DataSourceInstance& operator=(const DataSourceInstance&) = delete;
46660 
46661     DataSourceInstanceID instance_id;
46662     DataSourceConfig config;
46663     std::string data_source_name;
46664     bool will_notify_on_start;
46665     bool will_notify_on_stop;
46666     bool handles_incremental_state_clear;
46667 
46668     enum DataSourceInstanceState {
46669       CONFIGURED,
46670       STARTING,
46671       STARTED,
46672       STOPPING,
46673       STOPPED
46674     };
46675     DataSourceInstanceState state = CONFIGURED;
46676   };
46677 
46678   struct PendingFlush {
46679     std::set<ProducerID> producers;
46680     ConsumerEndpoint::FlushCallback callback;
PendingFlushperfetto::TracingServiceImpl::PendingFlush46681     explicit PendingFlush(decltype(callback) cb) : callback(std::move(cb)) {}
46682   };
46683 
46684   // Holds the state of a tracing session. A tracing session is uniquely bound
46685   // a specific Consumer. Each Consumer can own one or more sessions.
46686   struct TracingSession {
46687     enum State {
46688       DISABLED = 0,
46689       CONFIGURED,
46690       STARTED,
46691       DISABLING_WAITING_STOP_ACKS
46692     };
46693 
46694     TracingSession(TracingSessionID,
46695                    ConsumerEndpointImpl*,
46696                    const TraceConfig&,
46697                    base::TaskRunner*);
46698     TracingSession(TracingSession&&) = delete;
46699     TracingSession& operator=(TracingSession&&) = delete;
46700 
num_buffersperfetto::TracingServiceImpl::TracingSession46701     size_t num_buffers() const { return buffers_index.size(); }
46702 
delay_to_next_write_period_msperfetto::TracingServiceImpl::TracingSession46703     uint32_t delay_to_next_write_period_ms() const {
46704       PERFETTO_DCHECK(write_period_ms > 0);
46705       return write_period_ms -
46706              static_cast<uint32_t>(base::GetWallTimeMs().count() %
46707                                    write_period_ms);
46708     }
46709 
flush_timeout_msperfetto::TracingServiceImpl::TracingSession46710     uint32_t flush_timeout_ms() {
46711       uint32_t timeout_ms = config.flush_timeout_ms();
46712       return timeout_ms ? timeout_ms : kDefaultFlushTimeoutMs;
46713     }
46714 
data_source_stop_timeout_msperfetto::TracingServiceImpl::TracingSession46715     uint32_t data_source_stop_timeout_ms() {
46716       uint32_t timeout_ms = config.data_source_stop_timeout_ms();
46717       return timeout_ms ? timeout_ms : kDataSourceStopTimeoutMs;
46718     }
46719 
GetPacketSequenceIDperfetto::TracingServiceImpl::TracingSession46720     PacketSequenceID GetPacketSequenceID(ProducerID producer_id,
46721                                          WriterID writer_id) {
46722       auto key = std::make_pair(producer_id, writer_id);
46723       auto it = packet_sequence_ids.find(key);
46724       if (it != packet_sequence_ids.end())
46725         return it->second;
46726       // We shouldn't run out of sequence IDs (producer ID is 16 bit, writer IDs
46727       // are limited to 1024).
46728       static_assert(kMaxPacketSequenceID > kMaxProducerID * kMaxWriterID,
46729                     "PacketSequenceID value space doesn't cover service "
46730                     "sequence ID and all producer/writer ID combinations!");
46731       PERFETTO_DCHECK(last_packet_sequence_id < kMaxPacketSequenceID);
46732       PacketSequenceID sequence_id = ++last_packet_sequence_id;
46733       packet_sequence_ids[key] = sequence_id;
46734       return sequence_id;
46735     }
46736 
GetDataSourceInstanceperfetto::TracingServiceImpl::TracingSession46737     DataSourceInstance* GetDataSourceInstance(
46738         ProducerID producer_id,
46739         DataSourceInstanceID instance_id) {
46740       for (auto& inst_kv : data_source_instances) {
46741         if (inst_kv.first != producer_id ||
46742             inst_kv.second.instance_id != instance_id) {
46743           continue;
46744         }
46745         return &inst_kv.second;
46746       }
46747       return nullptr;
46748     }
46749 
AllDataSourceInstancesStartedperfetto::TracingServiceImpl::TracingSession46750     bool AllDataSourceInstancesStarted() {
46751       return std::all_of(
46752           data_source_instances.begin(), data_source_instances.end(),
46753           [](decltype(data_source_instances)::const_reference x) {
46754             return x.second.state == DataSourceInstance::STARTED;
46755           });
46756     }
46757 
AllDataSourceInstancesStoppedperfetto::TracingServiceImpl::TracingSession46758     bool AllDataSourceInstancesStopped() {
46759       return std::all_of(
46760           data_source_instances.begin(), data_source_instances.end(),
46761           [](decltype(data_source_instances)::const_reference x) {
46762             return x.second.state == DataSourceInstance::STOPPED;
46763           });
46764     }
46765 
46766     const TracingSessionID id;
46767 
46768     // The consumer that started the session.
46769     // Can be nullptr if the consumer detached from the session.
46770     ConsumerEndpointImpl* consumer_maybe_null;
46771 
46772     // Unix uid of the consumer. This is valid even after the consumer detaches
46773     // and does not change for the entire duration of the session. It is used to
46774     // prevent that a consumer re-attaches to a session from a different uid.
46775     uid_t const consumer_uid;
46776 
46777     // The list of triggers this session received while alive and the time they
46778     // were received at. This is used to insert 'fake' packets back to the
46779     // consumer so they can tell when some event happened. The order matches the
46780     // order they were received.
46781     struct TriggerInfo {
46782       uint64_t boot_time_ns;
46783       std::string trigger_name;
46784       std::string producer_name;
46785       uid_t producer_uid;
46786     };
46787     std::vector<TriggerInfo> received_triggers;
46788 
46789     // The trace config provided by the Consumer when calling
46790     // EnableTracing(), plus any updates performed by ChangeTraceConfig.
46791     TraceConfig config;
46792 
46793     // List of data source instances that have been enabled on the various
46794     // producers for this tracing session.
46795     // TODO(rsavitski): at the time of writing, the map structure is unused
46796     // (even when the calling code has a key). This is also an opportunity to
46797     // consider an alternative data type, e.g. a map of vectors.
46798     std::multimap<ProducerID, DataSourceInstance> data_source_instances;
46799 
46800     // For each Flush(N) request, keeps track of the set of producers for which
46801     // we are still awaiting a NotifyFlushComplete(N) ack.
46802     std::map<FlushRequestID, PendingFlush> pending_flushes;
46803 
46804     // Maps a per-trace-session buffer index into the corresponding global
46805     // BufferID (shared namespace amongst all consumers). This vector has as
46806     // many entries as |config.buffers_size()|.
46807     std::vector<BufferID> buffers_index;
46808 
46809     std::map<std::pair<ProducerID, WriterID>, PacketSequenceID>
46810         packet_sequence_ids;
46811     PacketSequenceID last_packet_sequence_id = kServicePacketSequenceID;
46812 
46813     // Whether we should emit the trace stats next time we reach EOF while
46814     // performing ReadBuffers.
46815     bool should_emit_stats = false;
46816 
46817     // Whether we should emit the sync marker the next time ReadBuffers() is
46818     // called.
46819     bool should_emit_sync_marker = false;
46820 
46821     // Whether we mirrored the trace config back to the trace output yet.
46822     bool did_emit_config = false;
46823 
46824     // Whether we put the system info into the trace output yet.
46825     bool did_emit_system_info = false;
46826 
46827     // The number of received triggers we've emitted into the trace output.
46828     size_t num_triggers_emitted_into_trace = 0;
46829 
46830     // Packets that failed validation of the TrustedPacket.
46831     uint64_t invalid_packets = 0;
46832 
46833     // Set to true on the first call to MaybeNotifyAllDataSourcesStarted().
46834     bool did_notify_all_data_source_started = false;
46835 
46836     // Stores all lifecycle events of a particular type (i.e. associated with a
46837     // single field id in the TracingServiceEvent proto).
46838     struct LifecycleEvent {
LifecycleEventperfetto::TracingServiceImpl::TracingSession::LifecycleEvent46839       LifecycleEvent(uint32_t f_id, uint32_t m_size = 1)
46840           : field_id(f_id), max_size(m_size), timestamps(m_size) {}
46841 
46842       // The field id of the event in the TracingServiceEvent proto.
46843       uint32_t field_id;
46844 
46845       // Stores the max size of |timestamps|. Set to 1 by default (in
46846       // the constructor) but can be overriden in TraceSession constructor
46847       // if a larger size is required.
46848       uint32_t max_size;
46849 
46850       // Stores the timestamps emitted for each event type (in nanoseconds).
46851       // Emitted into the trace and cleared when the consumer next calls
46852       // ReadBuffers.
46853       base::CircularQueue<int64_t> timestamps;
46854     };
46855     std::vector<LifecycleEvent> lifecycle_events;
46856 
46857     using ClockSnapshotData =
46858         std::vector<std::pair<uint32_t /*clock_id*/, uint64_t /*ts*/>>;
46859 
46860     // Initial clock snapshot, captured at trace start time (when state goes to
46861     // TracingSession::STARTED). Emitted into the trace when the consumer first
46862     // calls ReadBuffers().
46863     ClockSnapshotData initial_clock_snapshot;
46864 
46865     // Stores clock snapshots to emit into the trace as a ring buffer. This
46866     // buffer is populated both periodically and when lifecycle events happen
46867     // but only when significant clock drift is detected. Emitted into the trace
46868     // and cleared when the consumer next calls ReadBuffers().
46869     base::CircularQueue<ClockSnapshotData> clock_snapshot_ring_buffer;
46870 
46871     State state = DISABLED;
46872 
46873     // If the consumer detached the session, this variable defines the key used
46874     // for identifying the session later when reattaching.
46875     std::string detach_key;
46876 
46877     // This is set when the Consumer calls sets |write_into_file| == true in the
46878     // TraceConfig. In this case this represents the file we should stream the
46879     // trace packets into, rather than returning it to the consumer via
46880     // OnTraceData().
46881     base::ScopedFile write_into_file;
46882     uint32_t write_period_ms = 0;
46883     uint64_t max_file_size_bytes = 0;
46884     uint64_t bytes_written_into_file = 0;
46885 
46886     // Set when using SaveTraceForBugreport(). This callback will be called
46887     // when the tracing session ends and the data has been saved into the file.
46888     std::function<void()> on_disable_callback_for_bugreport;
46889     bool seized_for_bugreport = false;
46890 
46891     // Periodic task for snapshotting service events (e.g. clocks, sync markers
46892     // etc)
46893     base::PeriodicTask snapshot_periodic_task;
46894 
46895     // When non-NULL the packets should be post-processed using the filter.
46896     std::unique_ptr<protozero::MessageFilter> trace_filter;
46897     uint64_t filter_input_packets = 0;
46898     uint64_t filter_input_bytes = 0;
46899     uint64_t filter_output_bytes = 0;
46900     uint64_t filter_errors = 0;
46901   };
46902 
46903   TracingServiceImpl(const TracingServiceImpl&) = delete;
46904   TracingServiceImpl& operator=(const TracingServiceImpl&) = delete;
46905 
46906   DataSourceInstance* SetupDataSource(const TraceConfig::DataSource&,
46907                                       const TraceConfig::ProducerConfig&,
46908                                       const RegisteredDataSource&,
46909                                       TracingSession*);
46910 
46911   // Returns the next available ProducerID that is not in |producers_|.
46912   ProducerID GetNextProducerID();
46913 
46914   // Returns a pointer to the |tracing_sessions_| entry or nullptr if the
46915   // session doesn't exists.
46916   TracingSession* GetTracingSession(TracingSessionID);
46917 
46918   // Returns a pointer to the |tracing_sessions_| entry, matching the given
46919   // uid and detach key, or nullptr if no such session exists.
46920   TracingSession* GetDetachedSession(uid_t, const std::string& key);
46921 
46922   // Update the memory guard rail by using the latest information from the
46923   // shared memory and trace buffers.
46924   void UpdateMemoryGuardrail();
46925 
46926   void StartDataSourceInstance(ProducerEndpointImpl*,
46927                                TracingSession*,
46928                                DataSourceInstance*);
46929   void StopDataSourceInstance(ProducerEndpointImpl*,
46930                               TracingSession*,
46931                               DataSourceInstance*,
46932                               bool disable_immediately);
46933   void PeriodicSnapshotTask(TracingSessionID);
46934   void MaybeSnapshotClocksIntoRingBuffer(TracingSession*);
46935   bool SnapshotClocks(TracingSession::ClockSnapshotData*);
46936   void SnapshotLifecyleEvent(TracingSession*,
46937                              uint32_t field_id,
46938                              bool snapshot_clocks);
46939   void EmitClockSnapshot(TracingSession*,
46940                          TracingSession::ClockSnapshotData,
46941                          std::vector<TracePacket>*);
46942   void EmitSyncMarker(std::vector<TracePacket>*);
46943   void EmitStats(TracingSession*, std::vector<TracePacket>*);
46944   TraceStats GetTraceStats(TracingSession*);
46945   void EmitLifecycleEvents(TracingSession*, std::vector<TracePacket>*);
46946   void EmitSeizedForBugreportLifecycleEvent(std::vector<TracePacket>*);
46947   void MaybeEmitTraceConfig(TracingSession*, std::vector<TracePacket>*);
46948   void MaybeEmitSystemInfo(TracingSession*, std::vector<TracePacket>*);
46949   void MaybeEmitReceivedTriggers(TracingSession*, std::vector<TracePacket>*);
46950   void MaybeNotifyAllDataSourcesStarted(TracingSession*);
46951   bool MaybeSaveTraceForBugreport(std::function<void()> callback);
46952   void OnFlushTimeout(TracingSessionID, FlushRequestID);
46953   void OnDisableTracingTimeout(TracingSessionID);
46954   void DisableTracingNotifyConsumerAndFlushFile(TracingSession*);
46955   void PeriodicFlushTask(TracingSessionID, bool post_next_only);
46956   void CompleteFlush(TracingSessionID tsid,
46957                      ConsumerEndpoint::FlushCallback callback,
46958                      bool success);
46959   void ScrapeSharedMemoryBuffers(TracingSession*, ProducerEndpointImpl*);
46960   void PeriodicClearIncrementalStateTask(TracingSessionID, bool post_next_only);
46961   TraceBuffer* GetBufferByID(BufferID);
46962   void OnStartTriggersTimeout(TracingSessionID tsid);
46963   void MaybeLogUploadEvent(const TraceConfig&,
46964                            PerfettoStatsdAtom atom,
46965                            const std::string& trigger_name = "");
46966   void MaybeLogTriggerEvent(const TraceConfig&,
46967                             PerfettoTriggerAtom atom,
46968                             const std::string& trigger_name);
46969   size_t PurgeExpiredAndCountTriggerInWindow(int64_t now_ns,
46970                                              uint64_t trigger_name_hash);
46971 
46972   base::TaskRunner* const task_runner_;
46973   std::unique_ptr<SharedMemory::Factory> shm_factory_;
46974   ProducerID last_producer_id_ = 0;
46975   DataSourceInstanceID last_data_source_instance_id_ = 0;
46976   TracingSessionID last_tracing_session_id_ = 0;
46977   FlushRequestID last_flush_request_id_ = 0;
46978   uid_t uid_ = 0;
46979 
46980   // Buffer IDs are global across all consumers (because a Producer can produce
46981   // data for more than one trace session, hence more than one consumer).
46982   IdAllocator<BufferID> buffer_ids_;
46983 
46984   std::multimap<std::string /*name*/, RegisteredDataSource> data_sources_;
46985   std::map<ProducerID, ProducerEndpointImpl*> producers_;
46986   std::set<ConsumerEndpointImpl*> consumers_;
46987   std::map<TracingSessionID, TracingSession> tracing_sessions_;
46988   std::map<BufferID, std::unique_ptr<TraceBuffer>> buffers_;
46989   std::map<std::string, int64_t> session_to_last_trace_s_;
46990 
46991   // Contains timestamps of triggers.
46992   // The queue is sorted by timestamp and invocations older than
46993   // |trigger_window_ns_| are purged when a trigger happens.
46994   base::CircularQueue<TriggerHistory> trigger_history_;
46995 
46996   bool smb_scraping_enabled_ = false;
46997   bool lockdown_mode_ = false;
46998   uint32_t min_write_period_ms_ = 100;       // Overridable for testing.
46999   int64_t trigger_window_ns_ = kOneDayInNs;  // Overridable for testing.
47000 
47001   std::minstd_rand trigger_probability_rand_;
47002   std::uniform_real_distribution<> trigger_probability_dist_;
47003   double trigger_rnd_override_for_testing_ = 0;  // Overridable for testing.
47004 
47005   uint8_t sync_marker_packet_[32];  // Lazily initialized.
47006   size_t sync_marker_packet_size_ = 0;
47007 
47008   // Stats.
47009   uint64_t chunks_discarded_ = 0;
47010   uint64_t patches_discarded_ = 0;
47011 
47012   PERFETTO_THREAD_CHECKER(thread_checker_)
47013 
47014   base::WeakPtrFactory<TracingServiceImpl>
47015       weak_ptr_factory_;  // Keep at the end.
47016 };
47017 
47018 }  // namespace perfetto
47019 
47020 #endif  // SRC_TRACING_CORE_TRACING_SERVICE_IMPL_H_
47021 // gen_amalgamated begin header: include/perfetto/tracing/core/tracing_service_capabilities.h
47022 /*
47023  * Copyright (C) 2020 The Android Open Source Project
47024  *
47025  * Licensed under the Apache License, Version 2.0 (the "License");
47026  * you may not use this file except in compliance with the License.
47027  * You may obtain a copy of the License at
47028  *
47029  *      http://www.apache.org/licenses/LICENSE-2.0
47030  *
47031  * Unless required by applicable law or agreed to in writing, software
47032  * distributed under the License is distributed on an "AS IS" BASIS,
47033  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
47034  * See the License for the specific language governing permissions and
47035  * limitations under the License.
47036  */
47037 
47038 #ifndef INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_CAPABILITIES_H_
47039 #define INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_CAPABILITIES_H_
47040 
47041 // Creates the aliases in the ::perfetto namespace, doing things like:
47042 // using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
47043 // See comments in forward_decls.h for the historical reasons of this
47044 // indirection layer.
47045 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
47046 
47047 // gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_capabilities.gen.h"
47048 
47049 #endif  // INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_CAPABILITIES_H_
47050 // gen_amalgamated begin header: gen/protos/perfetto/common/trace_stats.pbzero.h
47051 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
47052 
47053 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACE_STATS_PROTO_H_
47054 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACE_STATS_PROTO_H_
47055 
47056 #include <stddef.h>
47057 #include <stdint.h>
47058 
47059 // gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
47060 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
47061 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
47062 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
47063 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
47064 
47065 namespace perfetto {
47066 namespace protos {
47067 namespace pbzero {
47068 
47069 class TraceStats_BufferStats;
47070 class TraceStats_FilterStats;
47071 
47072 class TraceStats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/11, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
47073  public:
TraceStats_Decoder(const uint8_t * data,size_t len)47074   TraceStats_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceStats_Decoder(const std::string & raw)47075   explicit TraceStats_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
TraceStats_Decoder(const::protozero::ConstBytes & raw)47076   explicit TraceStats_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_buffer_stats() const47077   bool has_buffer_stats() const { return at<1>().valid(); }
buffer_stats() const47078   ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> buffer_stats() const { return GetRepeated<::protozero::ConstBytes>(1); }
has_producers_connected() const47079   bool has_producers_connected() const { return at<2>().valid(); }
producers_connected() const47080   uint32_t producers_connected() const { return at<2>().as_uint32(); }
has_producers_seen() const47081   bool has_producers_seen() const { return at<3>().valid(); }
producers_seen() const47082   uint64_t producers_seen() const { return at<3>().as_uint64(); }
has_data_sources_registered() const47083   bool has_data_sources_registered() const { return at<4>().valid(); }
data_sources_registered() const47084   uint32_t data_sources_registered() const { return at<4>().as_uint32(); }
has_data_sources_seen() const47085   bool has_data_sources_seen() const { return at<5>().valid(); }
data_sources_seen() const47086   uint64_t data_sources_seen() const { return at<5>().as_uint64(); }
has_tracing_sessions() const47087   bool has_tracing_sessions() const { return at<6>().valid(); }
tracing_sessions() const47088   uint32_t tracing_sessions() const { return at<6>().as_uint32(); }
has_total_buffers() const47089   bool has_total_buffers() const { return at<7>().valid(); }
total_buffers() const47090   uint32_t total_buffers() const { return at<7>().as_uint32(); }
has_chunks_discarded() const47091   bool has_chunks_discarded() const { return at<8>().valid(); }
chunks_discarded() const47092   uint64_t chunks_discarded() const { return at<8>().as_uint64(); }
has_patches_discarded() const47093   bool has_patches_discarded() const { return at<9>().valid(); }
patches_discarded() const47094   uint64_t patches_discarded() const { return at<9>().as_uint64(); }
has_invalid_packets() const47095   bool has_invalid_packets() const { return at<10>().valid(); }
invalid_packets() const47096   uint64_t invalid_packets() const { return at<10>().as_uint64(); }
has_filter_stats() const47097   bool has_filter_stats() const { return at<11>().valid(); }
filter_stats() const47098   ::protozero::ConstBytes filter_stats() const { return at<11>().as_bytes(); }
47099 };
47100 
47101 class TraceStats : public ::protozero::Message {
47102  public:
47103   using Decoder = TraceStats_Decoder;
47104   enum : int32_t {
47105     kBufferStatsFieldNumber = 1,
47106     kProducersConnectedFieldNumber = 2,
47107     kProducersSeenFieldNumber = 3,
47108     kDataSourcesRegisteredFieldNumber = 4,
47109     kDataSourcesSeenFieldNumber = 5,
47110     kTracingSessionsFieldNumber = 6,
47111     kTotalBuffersFieldNumber = 7,
47112     kChunksDiscardedFieldNumber = 8,
47113     kPatchesDiscardedFieldNumber = 9,
47114     kInvalidPacketsFieldNumber = 10,
47115     kFilterStatsFieldNumber = 11,
47116   };
47117   using BufferStats = ::perfetto::protos::pbzero::TraceStats_BufferStats;
47118   using FilterStats = ::perfetto::protos::pbzero::TraceStats_FilterStats;
47119 
47120   using FieldMetadata_BufferStats =
47121     ::protozero::proto_utils::FieldMetadata<
47122       1,
47123       ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
47124       ::protozero::proto_utils::ProtoSchemaType::kMessage,
47125       TraceStats_BufferStats,
47126       TraceStats>;
47127 
47128   // Ceci n'est pas une pipe.
47129   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
47130   // type (and users are expected to use it as such, hence kCamelCase name).
47131   // It is declared as a function to keep protozero bindings header-only as
47132   // inline constexpr variables are not available until C++17 (while inline
47133   // functions are).
47134   // TODO(altimin): Use inline variable instead after adopting C++17.
kBufferStats()47135   static constexpr FieldMetadata_BufferStats kBufferStats() { return {}; }
add_buffer_stats()47136   template <typename T = TraceStats_BufferStats> T* add_buffer_stats() {
47137     return BeginNestedMessage<T>(1);
47138   }
47139 
47140 
47141   using FieldMetadata_ProducersConnected =
47142     ::protozero::proto_utils::FieldMetadata<
47143       2,
47144       ::protozero::proto_utils::RepetitionType::kNotRepeated,
47145       ::protozero::proto_utils::ProtoSchemaType::kUint32,
47146       uint32_t,
47147       TraceStats>;
47148 
47149   // Ceci n'est pas une pipe.
47150   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
47151   // type (and users are expected to use it as such, hence kCamelCase name).
47152   // It is declared as a function to keep protozero bindings header-only as
47153   // inline constexpr variables are not available until C++17 (while inline
47154   // functions are).
47155   // TODO(altimin): Use inline variable instead after adopting C++17.
kProducersConnected()47156   static constexpr FieldMetadata_ProducersConnected kProducersConnected() { return {}; }
set_producers_connected(uint32_t value)47157   void set_producers_connected(uint32_t value) {
47158     static constexpr uint32_t field_id = FieldMetadata_ProducersConnected::kFieldId;
47159     // Call the appropriate protozero::Message::Append(field_id, ...)
47160     // method based on the type of the field.
47161     ::protozero::internal::FieldWriter<
47162       ::protozero::proto_utils::ProtoSchemaType::kUint32>
47163         ::Append(*this, field_id, value);
47164   }
47165 
47166   using FieldMetadata_ProducersSeen =
47167     ::protozero::proto_utils::FieldMetadata<
47168       3,
47169       ::protozero::proto_utils::RepetitionType::kNotRepeated,
47170       ::protozero::proto_utils::ProtoSchemaType::kUint64,
47171       uint64_t,
47172       TraceStats>;
47173 
47174   // Ceci n'est pas une pipe.
47175   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
47176   // type (and users are expected to use it as such, hence kCamelCase name).
47177   // It is declared as a function to keep protozero bindings header-only as
47178   // inline constexpr variables are not available until C++17 (while inline
47179   // functions are).
47180   // TODO(altimin): Use inline variable instead after adopting C++17.
kProducersSeen()47181   static constexpr FieldMetadata_ProducersSeen kProducersSeen() { return {}; }
set_producers_seen(uint64_t value)47182   void set_producers_seen(uint64_t value) {
47183     static constexpr uint32_t field_id = FieldMetadata_ProducersSeen::kFieldId;
47184     // Call the appropriate protozero::Message::Append(field_id, ...)
47185     // method based on the type of the field.
47186     ::protozero::internal::FieldWriter<
47187       ::protozero::proto_utils::ProtoSchemaType::kUint64>
47188         ::Append(*this, field_id, value);
47189   }
47190 
47191   using FieldMetadata_DataSourcesRegistered =
47192     ::protozero::proto_utils::FieldMetadata<
47193       4,
47194       ::protozero::proto_utils::RepetitionType::kNotRepeated,
47195       ::protozero::proto_utils::ProtoSchemaType::kUint32,
47196       uint32_t,
47197       TraceStats>;
47198 
47199   // Ceci n'est pas une pipe.
47200   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
47201   // type (and users are expected to use it as such, hence kCamelCase name).
47202   // It is declared as a function to keep protozero bindings header-only as
47203   // inline constexpr variables are not available until C++17 (while inline
47204   // functions are).
47205   // TODO(altimin): Use inline variable instead after adopting C++17.
kDataSourcesRegistered()47206   static constexpr FieldMetadata_DataSourcesRegistered kDataSourcesRegistered() { return {}; }
set_data_sources_registered(uint32_t value)47207   void set_data_sources_registered(uint32_t value) {
47208     static constexpr uint32_t field_id = FieldMetadata_DataSourcesRegistered::kFieldId;
47209     // Call the appropriate protozero::Message::Append(field_id, ...)
47210     // method based on the type of the field.
47211     ::protozero::internal::FieldWriter<
47212       ::protozero::proto_utils::ProtoSchemaType::kUint32>
47213         ::Append(*this, field_id, value);
47214   }
47215 
47216   using FieldMetadata_DataSourcesSeen =
47217     ::protozero::proto_utils::FieldMetadata<
47218       5,
47219       ::protozero::proto_utils::RepetitionType::kNotRepeated,
47220       ::protozero::proto_utils::ProtoSchemaType::kUint64,
47221       uint64_t,
47222       TraceStats>;
47223 
47224   // Ceci n'est pas une pipe.
47225   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
47226   // type (and users are expected to use it as such, hence kCamelCase name).
47227   // It is declared as a function to keep protozero bindings header-only as
47228   // inline constexpr variables are not available until C++17 (while inline
47229   // functions are).
47230   // TODO(altimin): Use inline variable instead after adopting C++17.
kDataSourcesSeen()47231   static constexpr FieldMetadata_DataSourcesSeen kDataSourcesSeen() { return {}; }
set_data_sources_seen(uint64_t value)47232   void set_data_sources_seen(uint64_t value) {
47233     static constexpr uint32_t field_id = FieldMetadata_DataSourcesSeen::kFieldId;
47234     // Call the appropriate protozero::Message::Append(field_id, ...)
47235     // method based on the type of the field.
47236     ::protozero::internal::FieldWriter<
47237       ::protozero::proto_utils::ProtoSchemaType::kUint64>
47238         ::Append(*this, field_id, value);
47239   }
47240 
47241   using FieldMetadata_TracingSessions =
47242     ::protozero::proto_utils::FieldMetadata<
47243       6,
47244       ::protozero::proto_utils::RepetitionType::kNotRepeated,
47245       ::protozero::proto_utils::ProtoSchemaType::kUint32,
47246       uint32_t,
47247       TraceStats>;
47248 
47249   // Ceci n'est pas une pipe.
47250   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
47251   // type (and users are expected to use it as such, hence kCamelCase name).
47252   // It is declared as a function to keep protozero bindings header-only as
47253   // inline constexpr variables are not available until C++17 (while inline
47254   // functions are).
47255   // TODO(altimin): Use inline variable instead after adopting C++17.
kTracingSessions()47256   static constexpr FieldMetadata_TracingSessions kTracingSessions() { return {}; }
set_tracing_sessions(uint32_t value)47257   void set_tracing_sessions(uint32_t value) {
47258     static constexpr uint32_t field_id = FieldMetadata_TracingSessions::kFieldId;
47259     // Call the appropriate protozero::Message::Append(field_id, ...)
47260     // method based on the type of the field.
47261     ::protozero::internal::FieldWriter<
47262       ::protozero::proto_utils::ProtoSchemaType::kUint32>
47263         ::Append(*this, field_id, value);
47264   }
47265 
47266   using FieldMetadata_TotalBuffers =
47267     ::protozero::proto_utils::FieldMetadata<
47268       7,
47269       ::protozero::proto_utils::RepetitionType::kNotRepeated,
47270       ::protozero::proto_utils::ProtoSchemaType::kUint32,
47271       uint32_t,
47272       TraceStats>;
47273 
47274   // Ceci n'est pas une pipe.
47275   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
47276   // type (and users are expected to use it as such, hence kCamelCase name).
47277   // It is declared as a function to keep protozero bindings header-only as
47278   // inline constexpr variables are not available until C++17 (while inline
47279   // functions are).
47280   // TODO(altimin): Use inline variable instead after adopting C++17.
kTotalBuffers()47281   static constexpr FieldMetadata_TotalBuffers kTotalBuffers() { return {}; }
set_total_buffers(uint32_t value)47282   void set_total_buffers(uint32_t value) {
47283     static constexpr uint32_t field_id = FieldMetadata_TotalBuffers::kFieldId;
47284     // Call the appropriate protozero::Message::Append(field_id, ...)
47285     // method based on the type of the field.
47286     ::protozero::internal::FieldWriter<
47287       ::protozero::proto_utils::ProtoSchemaType::kUint32>
47288         ::Append(*this, field_id, value);
47289   }
47290 
47291   using FieldMetadata_ChunksDiscarded =
47292     ::protozero::proto_utils::FieldMetadata<
47293       8,
47294       ::protozero::proto_utils::RepetitionType::kNotRepeated,
47295       ::protozero::proto_utils::ProtoSchemaType::kUint64,
47296       uint64_t,
47297       TraceStats>;
47298 
47299   // Ceci n'est pas une pipe.
47300   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
47301   // type (and users are expected to use it as such, hence kCamelCase name).
47302   // It is declared as a function to keep protozero bindings header-only as
47303   // inline constexpr variables are not available until C++17 (while inline
47304   // functions are).
47305   // TODO(altimin): Use inline variable instead after adopting C++17.
kChunksDiscarded()47306   static constexpr FieldMetadata_ChunksDiscarded kChunksDiscarded() { return {}; }
set_chunks_discarded(uint64_t value)47307   void set_chunks_discarded(uint64_t value) {
47308     static constexpr uint32_t field_id = FieldMetadata_ChunksDiscarded::kFieldId;
47309     // Call the appropriate protozero::Message::Append(field_id, ...)
47310     // method based on the type of the field.
47311     ::protozero::internal::FieldWriter<
47312       ::protozero::proto_utils::ProtoSchemaType::kUint64>
47313         ::Append(*this, field_id, value);
47314   }
47315 
47316   using FieldMetadata_PatchesDiscarded =
47317     ::protozero::proto_utils::FieldMetadata<
47318       9,
47319       ::protozero::proto_utils::RepetitionType::kNotRepeated,
47320       ::protozero::proto_utils::ProtoSchemaType::kUint64,
47321       uint64_t,
47322       TraceStats>;
47323 
47324   // Ceci n'est pas une pipe.
47325   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
47326   // type (and users are expected to use it as such, hence kCamelCase name).
47327   // It is declared as a function to keep protozero bindings header-only as
47328   // inline constexpr variables are not available until C++17 (while inline
47329   // functions are).
47330   // TODO(altimin): Use inline variable instead after adopting C++17.
kPatchesDiscarded()47331   static constexpr FieldMetadata_PatchesDiscarded kPatchesDiscarded() { return {}; }
set_patches_discarded(uint64_t value)47332   void set_patches_discarded(uint64_t value) {
47333     static constexpr uint32_t field_id = FieldMetadata_PatchesDiscarded::kFieldId;
47334     // Call the appropriate protozero::Message::Append(field_id, ...)
47335     // method based on the type of the field.
47336     ::protozero::internal::FieldWriter<
47337       ::protozero::proto_utils::ProtoSchemaType::kUint64>
47338         ::Append(*this, field_id, value);
47339   }
47340 
47341   using FieldMetadata_InvalidPackets =
47342     ::protozero::proto_utils::FieldMetadata<
47343       10,
47344       ::protozero::proto_utils::RepetitionType::kNotRepeated,
47345       ::protozero::proto_utils::ProtoSchemaType::kUint64,
47346       uint64_t,
47347       TraceStats>;
47348 
47349   // Ceci n'est pas une pipe.
47350   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
47351   // type (and users are expected to use it as such, hence kCamelCase name).
47352   // It is declared as a function to keep protozero bindings header-only as
47353   // inline constexpr variables are not available until C++17 (while inline
47354   // functions are).
47355   // TODO(altimin): Use inline variable instead after adopting C++17.
kInvalidPackets()47356   static constexpr FieldMetadata_InvalidPackets kInvalidPackets() { return {}; }
set_invalid_packets(uint64_t value)47357   void set_invalid_packets(uint64_t value) {
47358     static constexpr uint32_t field_id = FieldMetadata_InvalidPackets::kFieldId;
47359     // Call the appropriate protozero::Message::Append(field_id, ...)
47360     // method based on the type of the field.
47361     ::protozero::internal::FieldWriter<
47362       ::protozero::proto_utils::ProtoSchemaType::kUint64>
47363         ::Append(*this, field_id, value);
47364   }
47365 
47366   using FieldMetadata_FilterStats =
47367     ::protozero::proto_utils::FieldMetadata<
47368       11,
47369       ::protozero::proto_utils::RepetitionType::kNotRepeated,
47370       ::protozero::proto_utils::ProtoSchemaType::kMessage,
47371       TraceStats_FilterStats,
47372       TraceStats>;
47373 
47374   // Ceci n'est pas une pipe.
47375   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
47376   // type (and users are expected to use it as such, hence kCamelCase name).
47377   // It is declared as a function to keep protozero bindings header-only as
47378   // inline constexpr variables are not available until C++17 (while inline
47379   // functions are).
47380   // TODO(altimin): Use inline variable instead after adopting C++17.
kFilterStats()47381   static constexpr FieldMetadata_FilterStats kFilterStats() { return {}; }
set_filter_stats()47382   template <typename T = TraceStats_FilterStats> T* set_filter_stats() {
47383     return BeginNestedMessage<T>(11);
47384   }
47385 
47386 };
47387 
47388 class TraceStats_FilterStats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
47389  public:
TraceStats_FilterStats_Decoder(const uint8_t * data,size_t len)47390   TraceStats_FilterStats_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceStats_FilterStats_Decoder(const std::string & raw)47391   explicit TraceStats_FilterStats_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
TraceStats_FilterStats_Decoder(const::protozero::ConstBytes & raw)47392   explicit TraceStats_FilterStats_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_input_packets() const47393   bool has_input_packets() const { return at<1>().valid(); }
input_packets() const47394   uint64_t input_packets() const { return at<1>().as_uint64(); }
has_input_bytes() const47395   bool has_input_bytes() const { return at<2>().valid(); }
input_bytes() const47396   uint64_t input_bytes() const { return at<2>().as_uint64(); }
has_output_bytes() const47397   bool has_output_bytes() const { return at<3>().valid(); }
output_bytes() const47398   uint64_t output_bytes() const { return at<3>().as_uint64(); }
has_errors() const47399   bool has_errors() const { return at<4>().valid(); }
errors() const47400   uint64_t errors() const { return at<4>().as_uint64(); }
47401 };
47402 
47403 class TraceStats_FilterStats : public ::protozero::Message {
47404  public:
47405   using Decoder = TraceStats_FilterStats_Decoder;
47406   enum : int32_t {
47407     kInputPacketsFieldNumber = 1,
47408     kInputBytesFieldNumber = 2,
47409     kOutputBytesFieldNumber = 3,
47410     kErrorsFieldNumber = 4,
47411   };
47412 
47413   using FieldMetadata_InputPackets =
47414     ::protozero::proto_utils::FieldMetadata<
47415       1,
47416       ::protozero::proto_utils::RepetitionType::kNotRepeated,
47417       ::protozero::proto_utils::ProtoSchemaType::kUint64,
47418       uint64_t,
47419       TraceStats_FilterStats>;
47420 
47421   // Ceci n'est pas une pipe.
47422   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
47423   // type (and users are expected to use it as such, hence kCamelCase name).
47424   // It is declared as a function to keep protozero bindings header-only as
47425   // inline constexpr variables are not available until C++17 (while inline
47426   // functions are).
47427   // TODO(altimin): Use inline variable instead after adopting C++17.
kInputPackets()47428   static constexpr FieldMetadata_InputPackets kInputPackets() { return {}; }
set_input_packets(uint64_t value)47429   void set_input_packets(uint64_t value) {
47430     static constexpr uint32_t field_id = FieldMetadata_InputPackets::kFieldId;
47431     // Call the appropriate protozero::Message::Append(field_id, ...)
47432     // method based on the type of the field.
47433     ::protozero::internal::FieldWriter<
47434       ::protozero::proto_utils::ProtoSchemaType::kUint64>
47435         ::Append(*this, field_id, value);
47436   }
47437 
47438   using FieldMetadata_InputBytes =
47439     ::protozero::proto_utils::FieldMetadata<
47440       2,
47441       ::protozero::proto_utils::RepetitionType::kNotRepeated,
47442       ::protozero::proto_utils::ProtoSchemaType::kUint64,
47443       uint64_t,
47444       TraceStats_FilterStats>;
47445 
47446   // Ceci n'est pas une pipe.
47447   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
47448   // type (and users are expected to use it as such, hence kCamelCase name).
47449   // It is declared as a function to keep protozero bindings header-only as
47450   // inline constexpr variables are not available until C++17 (while inline
47451   // functions are).
47452   // TODO(altimin): Use inline variable instead after adopting C++17.
kInputBytes()47453   static constexpr FieldMetadata_InputBytes kInputBytes() { return {}; }
set_input_bytes(uint64_t value)47454   void set_input_bytes(uint64_t value) {
47455     static constexpr uint32_t field_id = FieldMetadata_InputBytes::kFieldId;
47456     // Call the appropriate protozero::Message::Append(field_id, ...)
47457     // method based on the type of the field.
47458     ::protozero::internal::FieldWriter<
47459       ::protozero::proto_utils::ProtoSchemaType::kUint64>
47460         ::Append(*this, field_id, value);
47461   }
47462 
47463   using FieldMetadata_OutputBytes =
47464     ::protozero::proto_utils::FieldMetadata<
47465       3,
47466       ::protozero::proto_utils::RepetitionType::kNotRepeated,
47467       ::protozero::proto_utils::ProtoSchemaType::kUint64,
47468       uint64_t,
47469       TraceStats_FilterStats>;
47470 
47471   // Ceci n'est pas une pipe.
47472   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
47473   // type (and users are expected to use it as such, hence kCamelCase name).
47474   // It is declared as a function to keep protozero bindings header-only as
47475   // inline constexpr variables are not available until C++17 (while inline
47476   // functions are).
47477   // TODO(altimin): Use inline variable instead after adopting C++17.
kOutputBytes()47478   static constexpr FieldMetadata_OutputBytes kOutputBytes() { return {}; }
set_output_bytes(uint64_t value)47479   void set_output_bytes(uint64_t value) {
47480     static constexpr uint32_t field_id = FieldMetadata_OutputBytes::kFieldId;
47481     // Call the appropriate protozero::Message::Append(field_id, ...)
47482     // method based on the type of the field.
47483     ::protozero::internal::FieldWriter<
47484       ::protozero::proto_utils::ProtoSchemaType::kUint64>
47485         ::Append(*this, field_id, value);
47486   }
47487 
47488   using FieldMetadata_Errors =
47489     ::protozero::proto_utils::FieldMetadata<
47490       4,
47491       ::protozero::proto_utils::RepetitionType::kNotRepeated,
47492       ::protozero::proto_utils::ProtoSchemaType::kUint64,
47493       uint64_t,
47494       TraceStats_FilterStats>;
47495 
47496   // Ceci n'est pas une pipe.
47497   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
47498   // type (and users are expected to use it as such, hence kCamelCase name).
47499   // It is declared as a function to keep protozero bindings header-only as
47500   // inline constexpr variables are not available until C++17 (while inline
47501   // functions are).
47502   // TODO(altimin): Use inline variable instead after adopting C++17.
kErrors()47503   static constexpr FieldMetadata_Errors kErrors() { return {}; }
set_errors(uint64_t value)47504   void set_errors(uint64_t value) {
47505     static constexpr uint32_t field_id = FieldMetadata_Errors::kFieldId;
47506     // Call the appropriate protozero::Message::Append(field_id, ...)
47507     // method based on the type of the field.
47508     ::protozero::internal::FieldWriter<
47509       ::protozero::proto_utils::ProtoSchemaType::kUint64>
47510         ::Append(*this, field_id, value);
47511   }
47512 };
47513 
47514 class TraceStats_BufferStats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/19, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
47515  public:
TraceStats_BufferStats_Decoder(const uint8_t * data,size_t len)47516   TraceStats_BufferStats_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceStats_BufferStats_Decoder(const std::string & raw)47517   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)47518   explicit TraceStats_BufferStats_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_buffer_size() const47519   bool has_buffer_size() const { return at<12>().valid(); }
buffer_size() const47520   uint64_t buffer_size() const { return at<12>().as_uint64(); }
has_bytes_written() const47521   bool has_bytes_written() const { return at<1>().valid(); }
bytes_written() const47522   uint64_t bytes_written() const { return at<1>().as_uint64(); }
has_bytes_overwritten() const47523   bool has_bytes_overwritten() const { return at<13>().valid(); }
bytes_overwritten() const47524   uint64_t bytes_overwritten() const { return at<13>().as_uint64(); }
has_bytes_read() const47525   bool has_bytes_read() const { return at<14>().valid(); }
bytes_read() const47526   uint64_t bytes_read() const { return at<14>().as_uint64(); }
has_padding_bytes_written() const47527   bool has_padding_bytes_written() const { return at<15>().valid(); }
padding_bytes_written() const47528   uint64_t padding_bytes_written() const { return at<15>().as_uint64(); }
has_padding_bytes_cleared() const47529   bool has_padding_bytes_cleared() const { return at<16>().valid(); }
padding_bytes_cleared() const47530   uint64_t padding_bytes_cleared() const { return at<16>().as_uint64(); }
has_chunks_written() const47531   bool has_chunks_written() const { return at<2>().valid(); }
chunks_written() const47532   uint64_t chunks_written() const { return at<2>().as_uint64(); }
has_chunks_rewritten() const47533   bool has_chunks_rewritten() const { return at<10>().valid(); }
chunks_rewritten() const47534   uint64_t chunks_rewritten() const { return at<10>().as_uint64(); }
has_chunks_overwritten() const47535   bool has_chunks_overwritten() const { return at<3>().valid(); }
chunks_overwritten() const47536   uint64_t chunks_overwritten() const { return at<3>().as_uint64(); }
has_chunks_discarded() const47537   bool has_chunks_discarded() const { return at<18>().valid(); }
chunks_discarded() const47538   uint64_t chunks_discarded() const { return at<18>().as_uint64(); }
has_chunks_read() const47539   bool has_chunks_read() const { return at<17>().valid(); }
chunks_read() const47540   uint64_t chunks_read() const { return at<17>().as_uint64(); }
has_chunks_committed_out_of_order() const47541   bool has_chunks_committed_out_of_order() const { return at<11>().valid(); }
chunks_committed_out_of_order() const47542   uint64_t chunks_committed_out_of_order() const { return at<11>().as_uint64(); }
has_write_wrap_count() const47543   bool has_write_wrap_count() const { return at<4>().valid(); }
write_wrap_count() const47544   uint64_t write_wrap_count() const { return at<4>().as_uint64(); }
has_patches_succeeded() const47545   bool has_patches_succeeded() const { return at<5>().valid(); }
patches_succeeded() const47546   uint64_t patches_succeeded() const { return at<5>().as_uint64(); }
has_patches_failed() const47547   bool has_patches_failed() const { return at<6>().valid(); }
patches_failed() const47548   uint64_t patches_failed() const { return at<6>().as_uint64(); }
has_readaheads_succeeded() const47549   bool has_readaheads_succeeded() const { return at<7>().valid(); }
readaheads_succeeded() const47550   uint64_t readaheads_succeeded() const { return at<7>().as_uint64(); }
has_readaheads_failed() const47551   bool has_readaheads_failed() const { return at<8>().valid(); }
readaheads_failed() const47552   uint64_t readaheads_failed() const { return at<8>().as_uint64(); }
has_abi_violations() const47553   bool has_abi_violations() const { return at<9>().valid(); }
abi_violations() const47554   uint64_t abi_violations() const { return at<9>().as_uint64(); }
has_trace_writer_packet_loss() const47555   bool has_trace_writer_packet_loss() const { return at<19>().valid(); }
trace_writer_packet_loss() const47556   uint64_t trace_writer_packet_loss() const { return at<19>().as_uint64(); }
47557 };
47558 
47559 class TraceStats_BufferStats : public ::protozero::Message {
47560  public:
47561   using Decoder = TraceStats_BufferStats_Decoder;
47562   enum : int32_t {
47563     kBufferSizeFieldNumber = 12,
47564     kBytesWrittenFieldNumber = 1,
47565     kBytesOverwrittenFieldNumber = 13,
47566     kBytesReadFieldNumber = 14,
47567     kPaddingBytesWrittenFieldNumber = 15,
47568     kPaddingBytesClearedFieldNumber = 16,
47569     kChunksWrittenFieldNumber = 2,
47570     kChunksRewrittenFieldNumber = 10,
47571     kChunksOverwrittenFieldNumber = 3,
47572     kChunksDiscardedFieldNumber = 18,
47573     kChunksReadFieldNumber = 17,
47574     kChunksCommittedOutOfOrderFieldNumber = 11,
47575     kWriteWrapCountFieldNumber = 4,
47576     kPatchesSucceededFieldNumber = 5,
47577     kPatchesFailedFieldNumber = 6,
47578     kReadaheadsSucceededFieldNumber = 7,
47579     kReadaheadsFailedFieldNumber = 8,
47580     kAbiViolationsFieldNumber = 9,
47581     kTraceWriterPacketLossFieldNumber = 19,
47582   };
47583 
47584   using FieldMetadata_BufferSize =
47585     ::protozero::proto_utils::FieldMetadata<
47586       12,
47587       ::protozero::proto_utils::RepetitionType::kNotRepeated,
47588       ::protozero::proto_utils::ProtoSchemaType::kUint64,
47589       uint64_t,
47590       TraceStats_BufferStats>;
47591 
47592   // Ceci n'est pas une pipe.
47593   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
47594   // type (and users are expected to use it as such, hence kCamelCase name).
47595   // It is declared as a function to keep protozero bindings header-only as
47596   // inline constexpr variables are not available until C++17 (while inline
47597   // functions are).
47598   // TODO(altimin): Use inline variable instead after adopting C++17.
kBufferSize()47599   static constexpr FieldMetadata_BufferSize kBufferSize() { return {}; }
set_buffer_size(uint64_t value)47600   void set_buffer_size(uint64_t value) {
47601     static constexpr uint32_t field_id = FieldMetadata_BufferSize::kFieldId;
47602     // Call the appropriate protozero::Message::Append(field_id, ...)
47603     // method based on the type of the field.
47604     ::protozero::internal::FieldWriter<
47605       ::protozero::proto_utils::ProtoSchemaType::kUint64>
47606         ::Append(*this, field_id, value);
47607   }
47608 
47609   using FieldMetadata_BytesWritten =
47610     ::protozero::proto_utils::FieldMetadata<
47611       1,
47612       ::protozero::proto_utils::RepetitionType::kNotRepeated,
47613       ::protozero::proto_utils::ProtoSchemaType::kUint64,
47614       uint64_t,
47615       TraceStats_BufferStats>;
47616 
47617   // Ceci n'est pas une pipe.
47618   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
47619   // type (and users are expected to use it as such, hence kCamelCase name).
47620   // It is declared as a function to keep protozero bindings header-only as
47621   // inline constexpr variables are not available until C++17 (while inline
47622   // functions are).
47623   // TODO(altimin): Use inline variable instead after adopting C++17.
kBytesWritten()47624   static constexpr FieldMetadata_BytesWritten kBytesWritten() { return {}; }
set_bytes_written(uint64_t value)47625   void set_bytes_written(uint64_t value) {
47626     static constexpr uint32_t field_id = FieldMetadata_BytesWritten::kFieldId;
47627     // Call the appropriate protozero::Message::Append(field_id, ...)
47628     // method based on the type of the field.
47629     ::protozero::internal::FieldWriter<
47630       ::protozero::proto_utils::ProtoSchemaType::kUint64>
47631         ::Append(*this, field_id, value);
47632   }
47633 
47634   using FieldMetadata_BytesOverwritten =
47635     ::protozero::proto_utils::FieldMetadata<
47636       13,
47637       ::protozero::proto_utils::RepetitionType::kNotRepeated,
47638       ::protozero::proto_utils::ProtoSchemaType::kUint64,
47639       uint64_t,
47640       TraceStats_BufferStats>;
47641 
47642   // Ceci n'est pas une pipe.
47643   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
47644   // type (and users are expected to use it as such, hence kCamelCase name).
47645   // It is declared as a function to keep protozero bindings header-only as
47646   // inline constexpr variables are not available until C++17 (while inline
47647   // functions are).
47648   // TODO(altimin): Use inline variable instead after adopting C++17.
kBytesOverwritten()47649   static constexpr FieldMetadata_BytesOverwritten kBytesOverwritten() { return {}; }
set_bytes_overwritten(uint64_t value)47650   void set_bytes_overwritten(uint64_t value) {
47651     static constexpr uint32_t field_id = FieldMetadata_BytesOverwritten::kFieldId;
47652     // Call the appropriate protozero::Message::Append(field_id, ...)
47653     // method based on the type of the field.
47654     ::protozero::internal::FieldWriter<
47655       ::protozero::proto_utils::ProtoSchemaType::kUint64>
47656         ::Append(*this, field_id, value);
47657   }
47658 
47659   using FieldMetadata_BytesRead =
47660     ::protozero::proto_utils::FieldMetadata<
47661       14,
47662       ::protozero::proto_utils::RepetitionType::kNotRepeated,
47663       ::protozero::proto_utils::ProtoSchemaType::kUint64,
47664       uint64_t,
47665       TraceStats_BufferStats>;
47666 
47667   // Ceci n'est pas une pipe.
47668   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
47669   // type (and users are expected to use it as such, hence kCamelCase name).
47670   // It is declared as a function to keep protozero bindings header-only as
47671   // inline constexpr variables are not available until C++17 (while inline
47672   // functions are).
47673   // TODO(altimin): Use inline variable instead after adopting C++17.
kBytesRead()47674   static constexpr FieldMetadata_BytesRead kBytesRead() { return {}; }
set_bytes_read(uint64_t value)47675   void set_bytes_read(uint64_t value) {
47676     static constexpr uint32_t field_id = FieldMetadata_BytesRead::kFieldId;
47677     // Call the appropriate protozero::Message::Append(field_id, ...)
47678     // method based on the type of the field.
47679     ::protozero::internal::FieldWriter<
47680       ::protozero::proto_utils::ProtoSchemaType::kUint64>
47681         ::Append(*this, field_id, value);
47682   }
47683 
47684   using FieldMetadata_PaddingBytesWritten =
47685     ::protozero::proto_utils::FieldMetadata<
47686       15,
47687       ::protozero::proto_utils::RepetitionType::kNotRepeated,
47688       ::protozero::proto_utils::ProtoSchemaType::kUint64,
47689       uint64_t,
47690       TraceStats_BufferStats>;
47691 
47692   // Ceci n'est pas une pipe.
47693   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
47694   // type (and users are expected to use it as such, hence kCamelCase name).
47695   // It is declared as a function to keep protozero bindings header-only as
47696   // inline constexpr variables are not available until C++17 (while inline
47697   // functions are).
47698   // TODO(altimin): Use inline variable instead after adopting C++17.
kPaddingBytesWritten()47699   static constexpr FieldMetadata_PaddingBytesWritten kPaddingBytesWritten() { return {}; }
set_padding_bytes_written(uint64_t value)47700   void set_padding_bytes_written(uint64_t value) {
47701     static constexpr uint32_t field_id = FieldMetadata_PaddingBytesWritten::kFieldId;
47702     // Call the appropriate protozero::Message::Append(field_id, ...)
47703     // method based on the type of the field.
47704     ::protozero::internal::FieldWriter<
47705       ::protozero::proto_utils::ProtoSchemaType::kUint64>
47706         ::Append(*this, field_id, value);
47707   }
47708 
47709   using FieldMetadata_PaddingBytesCleared =
47710     ::protozero::proto_utils::FieldMetadata<
47711       16,
47712       ::protozero::proto_utils::RepetitionType::kNotRepeated,
47713       ::protozero::proto_utils::ProtoSchemaType::kUint64,
47714       uint64_t,
47715       TraceStats_BufferStats>;
47716 
47717   // Ceci n'est pas une pipe.
47718   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
47719   // type (and users are expected to use it as such, hence kCamelCase name).
47720   // It is declared as a function to keep protozero bindings header-only as
47721   // inline constexpr variables are not available until C++17 (while inline
47722   // functions are).
47723   // TODO(altimin): Use inline variable instead after adopting C++17.
kPaddingBytesCleared()47724   static constexpr FieldMetadata_PaddingBytesCleared kPaddingBytesCleared() { return {}; }
set_padding_bytes_cleared(uint64_t value)47725   void set_padding_bytes_cleared(uint64_t value) {
47726     static constexpr uint32_t field_id = FieldMetadata_PaddingBytesCleared::kFieldId;
47727     // Call the appropriate protozero::Message::Append(field_id, ...)
47728     // method based on the type of the field.
47729     ::protozero::internal::FieldWriter<
47730       ::protozero::proto_utils::ProtoSchemaType::kUint64>
47731         ::Append(*this, field_id, value);
47732   }
47733 
47734   using FieldMetadata_ChunksWritten =
47735     ::protozero::proto_utils::FieldMetadata<
47736       2,
47737       ::protozero::proto_utils::RepetitionType::kNotRepeated,
47738       ::protozero::proto_utils::ProtoSchemaType::kUint64,
47739       uint64_t,
47740       TraceStats_BufferStats>;
47741 
47742   // Ceci n'est pas une pipe.
47743   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
47744   // type (and users are expected to use it as such, hence kCamelCase name).
47745   // It is declared as a function to keep protozero bindings header-only as
47746   // inline constexpr variables are not available until C++17 (while inline
47747   // functions are).
47748   // TODO(altimin): Use inline variable instead after adopting C++17.
kChunksWritten()47749   static constexpr FieldMetadata_ChunksWritten kChunksWritten() { return {}; }
set_chunks_written(uint64_t value)47750   void set_chunks_written(uint64_t value) {
47751     static constexpr uint32_t field_id = FieldMetadata_ChunksWritten::kFieldId;
47752     // Call the appropriate protozero::Message::Append(field_id, ...)
47753     // method based on the type of the field.
47754     ::protozero::internal::FieldWriter<
47755       ::protozero::proto_utils::ProtoSchemaType::kUint64>
47756         ::Append(*this, field_id, value);
47757   }
47758 
47759   using FieldMetadata_ChunksRewritten =
47760     ::protozero::proto_utils::FieldMetadata<
47761       10,
47762       ::protozero::proto_utils::RepetitionType::kNotRepeated,
47763       ::protozero::proto_utils::ProtoSchemaType::kUint64,
47764       uint64_t,
47765       TraceStats_BufferStats>;
47766 
47767   // Ceci n'est pas une pipe.
47768   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
47769   // type (and users are expected to use it as such, hence kCamelCase name).
47770   // It is declared as a function to keep protozero bindings header-only as
47771   // inline constexpr variables are not available until C++17 (while inline
47772   // functions are).
47773   // TODO(altimin): Use inline variable instead after adopting C++17.
kChunksRewritten()47774   static constexpr FieldMetadata_ChunksRewritten kChunksRewritten() { return {}; }
set_chunks_rewritten(uint64_t value)47775   void set_chunks_rewritten(uint64_t value) {
47776     static constexpr uint32_t field_id = FieldMetadata_ChunksRewritten::kFieldId;
47777     // Call the appropriate protozero::Message::Append(field_id, ...)
47778     // method based on the type of the field.
47779     ::protozero::internal::FieldWriter<
47780       ::protozero::proto_utils::ProtoSchemaType::kUint64>
47781         ::Append(*this, field_id, value);
47782   }
47783 
47784   using FieldMetadata_ChunksOverwritten =
47785     ::protozero::proto_utils::FieldMetadata<
47786       3,
47787       ::protozero::proto_utils::RepetitionType::kNotRepeated,
47788       ::protozero::proto_utils::ProtoSchemaType::kUint64,
47789       uint64_t,
47790       TraceStats_BufferStats>;
47791 
47792   // Ceci n'est pas une pipe.
47793   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
47794   // type (and users are expected to use it as such, hence kCamelCase name).
47795   // It is declared as a function to keep protozero bindings header-only as
47796   // inline constexpr variables are not available until C++17 (while inline
47797   // functions are).
47798   // TODO(altimin): Use inline variable instead after adopting C++17.
kChunksOverwritten()47799   static constexpr FieldMetadata_ChunksOverwritten kChunksOverwritten() { return {}; }
set_chunks_overwritten(uint64_t value)47800   void set_chunks_overwritten(uint64_t value) {
47801     static constexpr uint32_t field_id = FieldMetadata_ChunksOverwritten::kFieldId;
47802     // Call the appropriate protozero::Message::Append(field_id, ...)
47803     // method based on the type of the field.
47804     ::protozero::internal::FieldWriter<
47805       ::protozero::proto_utils::ProtoSchemaType::kUint64>
47806         ::Append(*this, field_id, value);
47807   }
47808 
47809   using FieldMetadata_ChunksDiscarded =
47810     ::protozero::proto_utils::FieldMetadata<
47811       18,
47812       ::protozero::proto_utils::RepetitionType::kNotRepeated,
47813       ::protozero::proto_utils::ProtoSchemaType::kUint64,
47814       uint64_t,
47815       TraceStats_BufferStats>;
47816 
47817   // Ceci n'est pas une pipe.
47818   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
47819   // type (and users are expected to use it as such, hence kCamelCase name).
47820   // It is declared as a function to keep protozero bindings header-only as
47821   // inline constexpr variables are not available until C++17 (while inline
47822   // functions are).
47823   // TODO(altimin): Use inline variable instead after adopting C++17.
kChunksDiscarded()47824   static constexpr FieldMetadata_ChunksDiscarded kChunksDiscarded() { return {}; }
set_chunks_discarded(uint64_t value)47825   void set_chunks_discarded(uint64_t value) {
47826     static constexpr uint32_t field_id = FieldMetadata_ChunksDiscarded::kFieldId;
47827     // Call the appropriate protozero::Message::Append(field_id, ...)
47828     // method based on the type of the field.
47829     ::protozero::internal::FieldWriter<
47830       ::protozero::proto_utils::ProtoSchemaType::kUint64>
47831         ::Append(*this, field_id, value);
47832   }
47833 
47834   using FieldMetadata_ChunksRead =
47835     ::protozero::proto_utils::FieldMetadata<
47836       17,
47837       ::protozero::proto_utils::RepetitionType::kNotRepeated,
47838       ::protozero::proto_utils::ProtoSchemaType::kUint64,
47839       uint64_t,
47840       TraceStats_BufferStats>;
47841 
47842   // Ceci n'est pas une pipe.
47843   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
47844   // type (and users are expected to use it as such, hence kCamelCase name).
47845   // It is declared as a function to keep protozero bindings header-only as
47846   // inline constexpr variables are not available until C++17 (while inline
47847   // functions are).
47848   // TODO(altimin): Use inline variable instead after adopting C++17.
kChunksRead()47849   static constexpr FieldMetadata_ChunksRead kChunksRead() { return {}; }
set_chunks_read(uint64_t value)47850   void set_chunks_read(uint64_t value) {
47851     static constexpr uint32_t field_id = FieldMetadata_ChunksRead::kFieldId;
47852     // Call the appropriate protozero::Message::Append(field_id, ...)
47853     // method based on the type of the field.
47854     ::protozero::internal::FieldWriter<
47855       ::protozero::proto_utils::ProtoSchemaType::kUint64>
47856         ::Append(*this, field_id, value);
47857   }
47858 
47859   using FieldMetadata_ChunksCommittedOutOfOrder =
47860     ::protozero::proto_utils::FieldMetadata<
47861       11,
47862       ::protozero::proto_utils::RepetitionType::kNotRepeated,
47863       ::protozero::proto_utils::ProtoSchemaType::kUint64,
47864       uint64_t,
47865       TraceStats_BufferStats>;
47866 
47867   // Ceci n'est pas une pipe.
47868   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
47869   // type (and users are expected to use it as such, hence kCamelCase name).
47870   // It is declared as a function to keep protozero bindings header-only as
47871   // inline constexpr variables are not available until C++17 (while inline
47872   // functions are).
47873   // TODO(altimin): Use inline variable instead after adopting C++17.
kChunksCommittedOutOfOrder()47874   static constexpr FieldMetadata_ChunksCommittedOutOfOrder kChunksCommittedOutOfOrder() { return {}; }
set_chunks_committed_out_of_order(uint64_t value)47875   void set_chunks_committed_out_of_order(uint64_t value) {
47876     static constexpr uint32_t field_id = FieldMetadata_ChunksCommittedOutOfOrder::kFieldId;
47877     // Call the appropriate protozero::Message::Append(field_id, ...)
47878     // method based on the type of the field.
47879     ::protozero::internal::FieldWriter<
47880       ::protozero::proto_utils::ProtoSchemaType::kUint64>
47881         ::Append(*this, field_id, value);
47882   }
47883 
47884   using FieldMetadata_WriteWrapCount =
47885     ::protozero::proto_utils::FieldMetadata<
47886       4,
47887       ::protozero::proto_utils::RepetitionType::kNotRepeated,
47888       ::protozero::proto_utils::ProtoSchemaType::kUint64,
47889       uint64_t,
47890       TraceStats_BufferStats>;
47891 
47892   // Ceci n'est pas une pipe.
47893   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
47894   // type (and users are expected to use it as such, hence kCamelCase name).
47895   // It is declared as a function to keep protozero bindings header-only as
47896   // inline constexpr variables are not available until C++17 (while inline
47897   // functions are).
47898   // TODO(altimin): Use inline variable instead after adopting C++17.
kWriteWrapCount()47899   static constexpr FieldMetadata_WriteWrapCount kWriteWrapCount() { return {}; }
set_write_wrap_count(uint64_t value)47900   void set_write_wrap_count(uint64_t value) {
47901     static constexpr uint32_t field_id = FieldMetadata_WriteWrapCount::kFieldId;
47902     // Call the appropriate protozero::Message::Append(field_id, ...)
47903     // method based on the type of the field.
47904     ::protozero::internal::FieldWriter<
47905       ::protozero::proto_utils::ProtoSchemaType::kUint64>
47906         ::Append(*this, field_id, value);
47907   }
47908 
47909   using FieldMetadata_PatchesSucceeded =
47910     ::protozero::proto_utils::FieldMetadata<
47911       5,
47912       ::protozero::proto_utils::RepetitionType::kNotRepeated,
47913       ::protozero::proto_utils::ProtoSchemaType::kUint64,
47914       uint64_t,
47915       TraceStats_BufferStats>;
47916 
47917   // Ceci n'est pas une pipe.
47918   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
47919   // type (and users are expected to use it as such, hence kCamelCase name).
47920   // It is declared as a function to keep protozero bindings header-only as
47921   // inline constexpr variables are not available until C++17 (while inline
47922   // functions are).
47923   // TODO(altimin): Use inline variable instead after adopting C++17.
kPatchesSucceeded()47924   static constexpr FieldMetadata_PatchesSucceeded kPatchesSucceeded() { return {}; }
set_patches_succeeded(uint64_t value)47925   void set_patches_succeeded(uint64_t value) {
47926     static constexpr uint32_t field_id = FieldMetadata_PatchesSucceeded::kFieldId;
47927     // Call the appropriate protozero::Message::Append(field_id, ...)
47928     // method based on the type of the field.
47929     ::protozero::internal::FieldWriter<
47930       ::protozero::proto_utils::ProtoSchemaType::kUint64>
47931         ::Append(*this, field_id, value);
47932   }
47933 
47934   using FieldMetadata_PatchesFailed =
47935     ::protozero::proto_utils::FieldMetadata<
47936       6,
47937       ::protozero::proto_utils::RepetitionType::kNotRepeated,
47938       ::protozero::proto_utils::ProtoSchemaType::kUint64,
47939       uint64_t,
47940       TraceStats_BufferStats>;
47941 
47942   // Ceci n'est pas une pipe.
47943   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
47944   // type (and users are expected to use it as such, hence kCamelCase name).
47945   // It is declared as a function to keep protozero bindings header-only as
47946   // inline constexpr variables are not available until C++17 (while inline
47947   // functions are).
47948   // TODO(altimin): Use inline variable instead after adopting C++17.
kPatchesFailed()47949   static constexpr FieldMetadata_PatchesFailed kPatchesFailed() { return {}; }
set_patches_failed(uint64_t value)47950   void set_patches_failed(uint64_t value) {
47951     static constexpr uint32_t field_id = FieldMetadata_PatchesFailed::kFieldId;
47952     // Call the appropriate protozero::Message::Append(field_id, ...)
47953     // method based on the type of the field.
47954     ::protozero::internal::FieldWriter<
47955       ::protozero::proto_utils::ProtoSchemaType::kUint64>
47956         ::Append(*this, field_id, value);
47957   }
47958 
47959   using FieldMetadata_ReadaheadsSucceeded =
47960     ::protozero::proto_utils::FieldMetadata<
47961       7,
47962       ::protozero::proto_utils::RepetitionType::kNotRepeated,
47963       ::protozero::proto_utils::ProtoSchemaType::kUint64,
47964       uint64_t,
47965       TraceStats_BufferStats>;
47966 
47967   // Ceci n'est pas une pipe.
47968   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
47969   // type (and users are expected to use it as such, hence kCamelCase name).
47970   // It is declared as a function to keep protozero bindings header-only as
47971   // inline constexpr variables are not available until C++17 (while inline
47972   // functions are).
47973   // TODO(altimin): Use inline variable instead after adopting C++17.
kReadaheadsSucceeded()47974   static constexpr FieldMetadata_ReadaheadsSucceeded kReadaheadsSucceeded() { return {}; }
set_readaheads_succeeded(uint64_t value)47975   void set_readaheads_succeeded(uint64_t value) {
47976     static constexpr uint32_t field_id = FieldMetadata_ReadaheadsSucceeded::kFieldId;
47977     // Call the appropriate protozero::Message::Append(field_id, ...)
47978     // method based on the type of the field.
47979     ::protozero::internal::FieldWriter<
47980       ::protozero::proto_utils::ProtoSchemaType::kUint64>
47981         ::Append(*this, field_id, value);
47982   }
47983 
47984   using FieldMetadata_ReadaheadsFailed =
47985     ::protozero::proto_utils::FieldMetadata<
47986       8,
47987       ::protozero::proto_utils::RepetitionType::kNotRepeated,
47988       ::protozero::proto_utils::ProtoSchemaType::kUint64,
47989       uint64_t,
47990       TraceStats_BufferStats>;
47991 
47992   // Ceci n'est pas une pipe.
47993   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
47994   // type (and users are expected to use it as such, hence kCamelCase name).
47995   // It is declared as a function to keep protozero bindings header-only as
47996   // inline constexpr variables are not available until C++17 (while inline
47997   // functions are).
47998   // TODO(altimin): Use inline variable instead after adopting C++17.
kReadaheadsFailed()47999   static constexpr FieldMetadata_ReadaheadsFailed kReadaheadsFailed() { return {}; }
set_readaheads_failed(uint64_t value)48000   void set_readaheads_failed(uint64_t value) {
48001     static constexpr uint32_t field_id = FieldMetadata_ReadaheadsFailed::kFieldId;
48002     // Call the appropriate protozero::Message::Append(field_id, ...)
48003     // method based on the type of the field.
48004     ::protozero::internal::FieldWriter<
48005       ::protozero::proto_utils::ProtoSchemaType::kUint64>
48006         ::Append(*this, field_id, value);
48007   }
48008 
48009   using FieldMetadata_AbiViolations =
48010     ::protozero::proto_utils::FieldMetadata<
48011       9,
48012       ::protozero::proto_utils::RepetitionType::kNotRepeated,
48013       ::protozero::proto_utils::ProtoSchemaType::kUint64,
48014       uint64_t,
48015       TraceStats_BufferStats>;
48016 
48017   // Ceci n'est pas une pipe.
48018   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
48019   // type (and users are expected to use it as such, hence kCamelCase name).
48020   // It is declared as a function to keep protozero bindings header-only as
48021   // inline constexpr variables are not available until C++17 (while inline
48022   // functions are).
48023   // TODO(altimin): Use inline variable instead after adopting C++17.
kAbiViolations()48024   static constexpr FieldMetadata_AbiViolations kAbiViolations() { return {}; }
set_abi_violations(uint64_t value)48025   void set_abi_violations(uint64_t value) {
48026     static constexpr uint32_t field_id = FieldMetadata_AbiViolations::kFieldId;
48027     // Call the appropriate protozero::Message::Append(field_id, ...)
48028     // method based on the type of the field.
48029     ::protozero::internal::FieldWriter<
48030       ::protozero::proto_utils::ProtoSchemaType::kUint64>
48031         ::Append(*this, field_id, value);
48032   }
48033 
48034   using FieldMetadata_TraceWriterPacketLoss =
48035     ::protozero::proto_utils::FieldMetadata<
48036       19,
48037       ::protozero::proto_utils::RepetitionType::kNotRepeated,
48038       ::protozero::proto_utils::ProtoSchemaType::kUint64,
48039       uint64_t,
48040       TraceStats_BufferStats>;
48041 
48042   // Ceci n'est pas une pipe.
48043   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
48044   // type (and users are expected to use it as such, hence kCamelCase name).
48045   // It is declared as a function to keep protozero bindings header-only as
48046   // inline constexpr variables are not available until C++17 (while inline
48047   // functions are).
48048   // TODO(altimin): Use inline variable instead after adopting C++17.
kTraceWriterPacketLoss()48049   static constexpr FieldMetadata_TraceWriterPacketLoss kTraceWriterPacketLoss() { return {}; }
set_trace_writer_packet_loss(uint64_t value)48050   void set_trace_writer_packet_loss(uint64_t value) {
48051     static constexpr uint32_t field_id = FieldMetadata_TraceWriterPacketLoss::kFieldId;
48052     // Call the appropriate protozero::Message::Append(field_id, ...)
48053     // method based on the type of the field.
48054     ::protozero::internal::FieldWriter<
48055       ::protozero::proto_utils::ProtoSchemaType::kUint64>
48056         ::Append(*this, field_id, value);
48057   }
48058 };
48059 
48060 } // Namespace.
48061 } // Namespace.
48062 } // Namespace.
48063 #endif  // Include guard.
48064 // gen_amalgamated begin header: gen/protos/perfetto/config/trace_config.pbzero.h
48065 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
48066 
48067 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TRACE_CONFIG_PROTO_H_
48068 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TRACE_CONFIG_PROTO_H_
48069 
48070 #include <stddef.h>
48071 #include <stdint.h>
48072 
48073 // gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
48074 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
48075 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
48076 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
48077 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
48078 
48079 namespace perfetto {
48080 namespace protos {
48081 namespace pbzero {
48082 
48083 class DataSourceConfig;
48084 class TraceConfig_BufferConfig;
48085 class TraceConfig_BuiltinDataSource;
48086 class TraceConfig_DataSource;
48087 class TraceConfig_GuardrailOverrides;
48088 class TraceConfig_IncidentReportConfig;
48089 class TraceConfig_IncrementalStateConfig;
48090 class TraceConfig_ProducerConfig;
48091 class TraceConfig_StatsdMetadata;
48092 class TraceConfig_TraceFilter;
48093 class TraceConfig_TriggerConfig;
48094 class TraceConfig_TriggerConfig_Trigger;
48095 enum BuiltinClock : int32_t;
48096 enum TraceConfig_BufferConfig_FillPolicy : int32_t;
48097 enum TraceConfig_CompressionType : int32_t;
48098 enum TraceConfig_LockdownModeOperation : int32_t;
48099 enum TraceConfig_StatsdLogging : int32_t;
48100 enum TraceConfig_TriggerConfig_TriggerMode : int32_t;
48101 
48102 enum TraceConfig_LockdownModeOperation : int32_t {
48103   TraceConfig_LockdownModeOperation_LOCKDOWN_UNCHANGED = 0,
48104   TraceConfig_LockdownModeOperation_LOCKDOWN_CLEAR = 1,
48105   TraceConfig_LockdownModeOperation_LOCKDOWN_SET = 2,
48106 };
48107 
48108 const TraceConfig_LockdownModeOperation TraceConfig_LockdownModeOperation_MIN = TraceConfig_LockdownModeOperation_LOCKDOWN_UNCHANGED;
48109 const TraceConfig_LockdownModeOperation TraceConfig_LockdownModeOperation_MAX = TraceConfig_LockdownModeOperation_LOCKDOWN_SET;
48110 
48111 enum TraceConfig_CompressionType : int32_t {
48112   TraceConfig_CompressionType_COMPRESSION_TYPE_UNSPECIFIED = 0,
48113   TraceConfig_CompressionType_COMPRESSION_TYPE_DEFLATE = 1,
48114 };
48115 
48116 const TraceConfig_CompressionType TraceConfig_CompressionType_MIN = TraceConfig_CompressionType_COMPRESSION_TYPE_UNSPECIFIED;
48117 const TraceConfig_CompressionType TraceConfig_CompressionType_MAX = TraceConfig_CompressionType_COMPRESSION_TYPE_DEFLATE;
48118 
48119 enum TraceConfig_StatsdLogging : int32_t {
48120   TraceConfig_StatsdLogging_STATSD_LOGGING_UNSPECIFIED = 0,
48121   TraceConfig_StatsdLogging_STATSD_LOGGING_ENABLED = 1,
48122   TraceConfig_StatsdLogging_STATSD_LOGGING_DISABLED = 2,
48123 };
48124 
48125 const TraceConfig_StatsdLogging TraceConfig_StatsdLogging_MIN = TraceConfig_StatsdLogging_STATSD_LOGGING_UNSPECIFIED;
48126 const TraceConfig_StatsdLogging TraceConfig_StatsdLogging_MAX = TraceConfig_StatsdLogging_STATSD_LOGGING_DISABLED;
48127 
48128 enum TraceConfig_TriggerConfig_TriggerMode : int32_t {
48129   TraceConfig_TriggerConfig_TriggerMode_UNSPECIFIED = 0,
48130   TraceConfig_TriggerConfig_TriggerMode_START_TRACING = 1,
48131   TraceConfig_TriggerConfig_TriggerMode_STOP_TRACING = 2,
48132 };
48133 
48134 const TraceConfig_TriggerConfig_TriggerMode TraceConfig_TriggerConfig_TriggerMode_MIN = TraceConfig_TriggerConfig_TriggerMode_UNSPECIFIED;
48135 const TraceConfig_TriggerConfig_TriggerMode TraceConfig_TriggerConfig_TriggerMode_MAX = TraceConfig_TriggerConfig_TriggerMode_STOP_TRACING;
48136 
48137 enum TraceConfig_BufferConfig_FillPolicy : int32_t {
48138   TraceConfig_BufferConfig_FillPolicy_UNSPECIFIED = 0,
48139   TraceConfig_BufferConfig_FillPolicy_RING_BUFFER = 1,
48140   TraceConfig_BufferConfig_FillPolicy_DISCARD = 2,
48141 };
48142 
48143 const TraceConfig_BufferConfig_FillPolicy TraceConfig_BufferConfig_FillPolicy_MIN = TraceConfig_BufferConfig_FillPolicy_UNSPECIFIED;
48144 const TraceConfig_BufferConfig_FillPolicy TraceConfig_BufferConfig_FillPolicy_MAX = TraceConfig_BufferConfig_FillPolicy_DISCARD;
48145 
48146 class TraceConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/32, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
48147  public:
TraceConfig_Decoder(const uint8_t * data,size_t len)48148   TraceConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_Decoder(const std::string & raw)48149   explicit TraceConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
TraceConfig_Decoder(const::protozero::ConstBytes & raw)48150   explicit TraceConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_buffers() const48151   bool has_buffers() const { return at<1>().valid(); }
buffers() const48152   ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> buffers() const { return GetRepeated<::protozero::ConstBytes>(1); }
has_data_sources() const48153   bool has_data_sources() const { return at<2>().valid(); }
data_sources() const48154   ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> data_sources() const { return GetRepeated<::protozero::ConstBytes>(2); }
has_builtin_data_sources() const48155   bool has_builtin_data_sources() const { return at<20>().valid(); }
builtin_data_sources() const48156   ::protozero::ConstBytes builtin_data_sources() const { return at<20>().as_bytes(); }
has_duration_ms() const48157   bool has_duration_ms() const { return at<3>().valid(); }
duration_ms() const48158   uint32_t duration_ms() const { return at<3>().as_uint32(); }
has_enable_extra_guardrails() const48159   bool has_enable_extra_guardrails() const { return at<4>().valid(); }
enable_extra_guardrails() const48160   bool enable_extra_guardrails() const { return at<4>().as_bool(); }
has_lockdown_mode() const48161   bool has_lockdown_mode() const { return at<5>().valid(); }
lockdown_mode() const48162   int32_t lockdown_mode() const { return at<5>().as_int32(); }
has_producers() const48163   bool has_producers() const { return at<6>().valid(); }
producers() const48164   ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> producers() const { return GetRepeated<::protozero::ConstBytes>(6); }
has_statsd_metadata() const48165   bool has_statsd_metadata() const { return at<7>().valid(); }
statsd_metadata() const48166   ::protozero::ConstBytes statsd_metadata() const { return at<7>().as_bytes(); }
has_write_into_file() const48167   bool has_write_into_file() const { return at<8>().valid(); }
write_into_file() const48168   bool write_into_file() const { return at<8>().as_bool(); }
has_output_path() const48169   bool has_output_path() const { return at<29>().valid(); }
output_path() const48170   ::protozero::ConstChars output_path() const { return at<29>().as_string(); }
has_file_write_period_ms() const48171   bool has_file_write_period_ms() const { return at<9>().valid(); }
file_write_period_ms() const48172   uint32_t file_write_period_ms() const { return at<9>().as_uint32(); }
has_max_file_size_bytes() const48173   bool has_max_file_size_bytes() const { return at<10>().valid(); }
max_file_size_bytes() const48174   uint64_t max_file_size_bytes() const { return at<10>().as_uint64(); }
has_guardrail_overrides() const48175   bool has_guardrail_overrides() const { return at<11>().valid(); }
guardrail_overrides() const48176   ::protozero::ConstBytes guardrail_overrides() const { return at<11>().as_bytes(); }
has_deferred_start() const48177   bool has_deferred_start() const { return at<12>().valid(); }
deferred_start() const48178   bool deferred_start() const { return at<12>().as_bool(); }
has_flush_period_ms() const48179   bool has_flush_period_ms() const { return at<13>().valid(); }
flush_period_ms() const48180   uint32_t flush_period_ms() const { return at<13>().as_uint32(); }
has_flush_timeout_ms() const48181   bool has_flush_timeout_ms() const { return at<14>().valid(); }
flush_timeout_ms() const48182   uint32_t flush_timeout_ms() const { return at<14>().as_uint32(); }
has_data_source_stop_timeout_ms() const48183   bool has_data_source_stop_timeout_ms() const { return at<23>().valid(); }
data_source_stop_timeout_ms() const48184   uint32_t data_source_stop_timeout_ms() const { return at<23>().as_uint32(); }
has_notify_traceur() const48185   bool has_notify_traceur() const { return at<16>().valid(); }
notify_traceur() const48186   bool notify_traceur() const { return at<16>().as_bool(); }
has_bugreport_score() const48187   bool has_bugreport_score() const { return at<30>().valid(); }
bugreport_score() const48188   int32_t bugreport_score() const { return at<30>().as_int32(); }
has_trigger_config() const48189   bool has_trigger_config() const { return at<17>().valid(); }
trigger_config() const48190   ::protozero::ConstBytes trigger_config() const { return at<17>().as_bytes(); }
has_activate_triggers() const48191   bool has_activate_triggers() const { return at<18>().valid(); }
activate_triggers() const48192   ::protozero::RepeatedFieldIterator<::protozero::ConstChars> activate_triggers() const { return GetRepeated<::protozero::ConstChars>(18); }
has_incremental_state_config() const48193   bool has_incremental_state_config() const { return at<21>().valid(); }
incremental_state_config() const48194   ::protozero::ConstBytes incremental_state_config() const { return at<21>().as_bytes(); }
has_allow_user_build_tracing() const48195   bool has_allow_user_build_tracing() const { return at<19>().valid(); }
allow_user_build_tracing() const48196   bool allow_user_build_tracing() const { return at<19>().as_bool(); }
has_unique_session_name() const48197   bool has_unique_session_name() const { return at<22>().valid(); }
unique_session_name() const48198   ::protozero::ConstChars unique_session_name() const { return at<22>().as_string(); }
has_compression_type() const48199   bool has_compression_type() const { return at<24>().valid(); }
compression_type() const48200   int32_t compression_type() const { return at<24>().as_int32(); }
has_incident_report_config() const48201   bool has_incident_report_config() const { return at<25>().valid(); }
incident_report_config() const48202   ::protozero::ConstBytes incident_report_config() const { return at<25>().as_bytes(); }
has_statsd_logging() const48203   bool has_statsd_logging() const { return at<31>().valid(); }
statsd_logging() const48204   int32_t statsd_logging() const { return at<31>().as_int32(); }
has_trace_uuid_msb() const48205   bool has_trace_uuid_msb() const { return at<27>().valid(); }
trace_uuid_msb() const48206   int64_t trace_uuid_msb() const { return at<27>().as_int64(); }
has_trace_uuid_lsb() const48207   bool has_trace_uuid_lsb() const { return at<28>().valid(); }
trace_uuid_lsb() const48208   int64_t trace_uuid_lsb() const { return at<28>().as_int64(); }
has_trace_filter() const48209   bool has_trace_filter() const { return at<32>().valid(); }
trace_filter() const48210   ::protozero::ConstBytes trace_filter() const { return at<32>().as_bytes(); }
48211 };
48212 
48213 class TraceConfig : public ::protozero::Message {
48214  public:
48215   using Decoder = TraceConfig_Decoder;
48216   enum : int32_t {
48217     kBuffersFieldNumber = 1,
48218     kDataSourcesFieldNumber = 2,
48219     kBuiltinDataSourcesFieldNumber = 20,
48220     kDurationMsFieldNumber = 3,
48221     kEnableExtraGuardrailsFieldNumber = 4,
48222     kLockdownModeFieldNumber = 5,
48223     kProducersFieldNumber = 6,
48224     kStatsdMetadataFieldNumber = 7,
48225     kWriteIntoFileFieldNumber = 8,
48226     kOutputPathFieldNumber = 29,
48227     kFileWritePeriodMsFieldNumber = 9,
48228     kMaxFileSizeBytesFieldNumber = 10,
48229     kGuardrailOverridesFieldNumber = 11,
48230     kDeferredStartFieldNumber = 12,
48231     kFlushPeriodMsFieldNumber = 13,
48232     kFlushTimeoutMsFieldNumber = 14,
48233     kDataSourceStopTimeoutMsFieldNumber = 23,
48234     kNotifyTraceurFieldNumber = 16,
48235     kBugreportScoreFieldNumber = 30,
48236     kTriggerConfigFieldNumber = 17,
48237     kActivateTriggersFieldNumber = 18,
48238     kIncrementalStateConfigFieldNumber = 21,
48239     kAllowUserBuildTracingFieldNumber = 19,
48240     kUniqueSessionNameFieldNumber = 22,
48241     kCompressionTypeFieldNumber = 24,
48242     kIncidentReportConfigFieldNumber = 25,
48243     kStatsdLoggingFieldNumber = 31,
48244     kTraceUuidMsbFieldNumber = 27,
48245     kTraceUuidLsbFieldNumber = 28,
48246     kTraceFilterFieldNumber = 32,
48247   };
48248   using BufferConfig = ::perfetto::protos::pbzero::TraceConfig_BufferConfig;
48249   using DataSource = ::perfetto::protos::pbzero::TraceConfig_DataSource;
48250   using BuiltinDataSource = ::perfetto::protos::pbzero::TraceConfig_BuiltinDataSource;
48251   using ProducerConfig = ::perfetto::protos::pbzero::TraceConfig_ProducerConfig;
48252   using StatsdMetadata = ::perfetto::protos::pbzero::TraceConfig_StatsdMetadata;
48253   using GuardrailOverrides = ::perfetto::protos::pbzero::TraceConfig_GuardrailOverrides;
48254   using TriggerConfig = ::perfetto::protos::pbzero::TraceConfig_TriggerConfig;
48255   using IncrementalStateConfig = ::perfetto::protos::pbzero::TraceConfig_IncrementalStateConfig;
48256   using IncidentReportConfig = ::perfetto::protos::pbzero::TraceConfig_IncidentReportConfig;
48257   using TraceFilter = ::perfetto::protos::pbzero::TraceConfig_TraceFilter;
48258   using LockdownModeOperation = ::perfetto::protos::pbzero::TraceConfig_LockdownModeOperation;
48259   using CompressionType = ::perfetto::protos::pbzero::TraceConfig_CompressionType;
48260   using StatsdLogging = ::perfetto::protos::pbzero::TraceConfig_StatsdLogging;
48261   static const LockdownModeOperation LOCKDOWN_UNCHANGED = TraceConfig_LockdownModeOperation_LOCKDOWN_UNCHANGED;
48262   static const LockdownModeOperation LOCKDOWN_CLEAR = TraceConfig_LockdownModeOperation_LOCKDOWN_CLEAR;
48263   static const LockdownModeOperation LOCKDOWN_SET = TraceConfig_LockdownModeOperation_LOCKDOWN_SET;
48264   static const CompressionType COMPRESSION_TYPE_UNSPECIFIED = TraceConfig_CompressionType_COMPRESSION_TYPE_UNSPECIFIED;
48265   static const CompressionType COMPRESSION_TYPE_DEFLATE = TraceConfig_CompressionType_COMPRESSION_TYPE_DEFLATE;
48266   static const StatsdLogging STATSD_LOGGING_UNSPECIFIED = TraceConfig_StatsdLogging_STATSD_LOGGING_UNSPECIFIED;
48267   static const StatsdLogging STATSD_LOGGING_ENABLED = TraceConfig_StatsdLogging_STATSD_LOGGING_ENABLED;
48268   static const StatsdLogging STATSD_LOGGING_DISABLED = TraceConfig_StatsdLogging_STATSD_LOGGING_DISABLED;
48269 
48270   using FieldMetadata_Buffers =
48271     ::protozero::proto_utils::FieldMetadata<
48272       1,
48273       ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
48274       ::protozero::proto_utils::ProtoSchemaType::kMessage,
48275       TraceConfig_BufferConfig,
48276       TraceConfig>;
48277 
48278   // Ceci n'est pas une pipe.
48279   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
48280   // type (and users are expected to use it as such, hence kCamelCase name).
48281   // It is declared as a function to keep protozero bindings header-only as
48282   // inline constexpr variables are not available until C++17 (while inline
48283   // functions are).
48284   // TODO(altimin): Use inline variable instead after adopting C++17.
kBuffers()48285   static constexpr FieldMetadata_Buffers kBuffers() { return {}; }
add_buffers()48286   template <typename T = TraceConfig_BufferConfig> T* add_buffers() {
48287     return BeginNestedMessage<T>(1);
48288   }
48289 
48290 
48291   using FieldMetadata_DataSources =
48292     ::protozero::proto_utils::FieldMetadata<
48293       2,
48294       ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
48295       ::protozero::proto_utils::ProtoSchemaType::kMessage,
48296       TraceConfig_DataSource,
48297       TraceConfig>;
48298 
48299   // Ceci n'est pas une pipe.
48300   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
48301   // type (and users are expected to use it as such, hence kCamelCase name).
48302   // It is declared as a function to keep protozero bindings header-only as
48303   // inline constexpr variables are not available until C++17 (while inline
48304   // functions are).
48305   // TODO(altimin): Use inline variable instead after adopting C++17.
kDataSources()48306   static constexpr FieldMetadata_DataSources kDataSources() { return {}; }
add_data_sources()48307   template <typename T = TraceConfig_DataSource> T* add_data_sources() {
48308     return BeginNestedMessage<T>(2);
48309   }
48310 
48311 
48312   using FieldMetadata_BuiltinDataSources =
48313     ::protozero::proto_utils::FieldMetadata<
48314       20,
48315       ::protozero::proto_utils::RepetitionType::kNotRepeated,
48316       ::protozero::proto_utils::ProtoSchemaType::kMessage,
48317       TraceConfig_BuiltinDataSource,
48318       TraceConfig>;
48319 
48320   // Ceci n'est pas une pipe.
48321   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
48322   // type (and users are expected to use it as such, hence kCamelCase name).
48323   // It is declared as a function to keep protozero bindings header-only as
48324   // inline constexpr variables are not available until C++17 (while inline
48325   // functions are).
48326   // TODO(altimin): Use inline variable instead after adopting C++17.
kBuiltinDataSources()48327   static constexpr FieldMetadata_BuiltinDataSources kBuiltinDataSources() { return {}; }
set_builtin_data_sources()48328   template <typename T = TraceConfig_BuiltinDataSource> T* set_builtin_data_sources() {
48329     return BeginNestedMessage<T>(20);
48330   }
48331 
48332 
48333   using FieldMetadata_DurationMs =
48334     ::protozero::proto_utils::FieldMetadata<
48335       3,
48336       ::protozero::proto_utils::RepetitionType::kNotRepeated,
48337       ::protozero::proto_utils::ProtoSchemaType::kUint32,
48338       uint32_t,
48339       TraceConfig>;
48340 
48341   // Ceci n'est pas une pipe.
48342   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
48343   // type (and users are expected to use it as such, hence kCamelCase name).
48344   // It is declared as a function to keep protozero bindings header-only as
48345   // inline constexpr variables are not available until C++17 (while inline
48346   // functions are).
48347   // TODO(altimin): Use inline variable instead after adopting C++17.
kDurationMs()48348   static constexpr FieldMetadata_DurationMs kDurationMs() { return {}; }
set_duration_ms(uint32_t value)48349   void set_duration_ms(uint32_t value) {
48350     static constexpr uint32_t field_id = FieldMetadata_DurationMs::kFieldId;
48351     // Call the appropriate protozero::Message::Append(field_id, ...)
48352     // method based on the type of the field.
48353     ::protozero::internal::FieldWriter<
48354       ::protozero::proto_utils::ProtoSchemaType::kUint32>
48355         ::Append(*this, field_id, value);
48356   }
48357 
48358   using FieldMetadata_EnableExtraGuardrails =
48359     ::protozero::proto_utils::FieldMetadata<
48360       4,
48361       ::protozero::proto_utils::RepetitionType::kNotRepeated,
48362       ::protozero::proto_utils::ProtoSchemaType::kBool,
48363       bool,
48364       TraceConfig>;
48365 
48366   // Ceci n'est pas une pipe.
48367   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
48368   // type (and users are expected to use it as such, hence kCamelCase name).
48369   // It is declared as a function to keep protozero bindings header-only as
48370   // inline constexpr variables are not available until C++17 (while inline
48371   // functions are).
48372   // TODO(altimin): Use inline variable instead after adopting C++17.
kEnableExtraGuardrails()48373   static constexpr FieldMetadata_EnableExtraGuardrails kEnableExtraGuardrails() { return {}; }
set_enable_extra_guardrails(bool value)48374   void set_enable_extra_guardrails(bool value) {
48375     static constexpr uint32_t field_id = FieldMetadata_EnableExtraGuardrails::kFieldId;
48376     // Call the appropriate protozero::Message::Append(field_id, ...)
48377     // method based on the type of the field.
48378     ::protozero::internal::FieldWriter<
48379       ::protozero::proto_utils::ProtoSchemaType::kBool>
48380         ::Append(*this, field_id, value);
48381   }
48382 
48383   using FieldMetadata_LockdownMode =
48384     ::protozero::proto_utils::FieldMetadata<
48385       5,
48386       ::protozero::proto_utils::RepetitionType::kNotRepeated,
48387       ::protozero::proto_utils::ProtoSchemaType::kEnum,
48388       ::perfetto::protos::pbzero::TraceConfig_LockdownModeOperation,
48389       TraceConfig>;
48390 
48391   // Ceci n'est pas une pipe.
48392   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
48393   // type (and users are expected to use it as such, hence kCamelCase name).
48394   // It is declared as a function to keep protozero bindings header-only as
48395   // inline constexpr variables are not available until C++17 (while inline
48396   // functions are).
48397   // TODO(altimin): Use inline variable instead after adopting C++17.
kLockdownMode()48398   static constexpr FieldMetadata_LockdownMode kLockdownMode() { return {}; }
set_lockdown_mode(::perfetto::protos::pbzero::TraceConfig_LockdownModeOperation value)48399   void set_lockdown_mode(::perfetto::protos::pbzero::TraceConfig_LockdownModeOperation value) {
48400     static constexpr uint32_t field_id = FieldMetadata_LockdownMode::kFieldId;
48401     // Call the appropriate protozero::Message::Append(field_id, ...)
48402     // method based on the type of the field.
48403     ::protozero::internal::FieldWriter<
48404       ::protozero::proto_utils::ProtoSchemaType::kEnum>
48405         ::Append(*this, field_id, value);
48406   }
48407 
48408   using FieldMetadata_Producers =
48409     ::protozero::proto_utils::FieldMetadata<
48410       6,
48411       ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
48412       ::protozero::proto_utils::ProtoSchemaType::kMessage,
48413       TraceConfig_ProducerConfig,
48414       TraceConfig>;
48415 
48416   // Ceci n'est pas une pipe.
48417   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
48418   // type (and users are expected to use it as such, hence kCamelCase name).
48419   // It is declared as a function to keep protozero bindings header-only as
48420   // inline constexpr variables are not available until C++17 (while inline
48421   // functions are).
48422   // TODO(altimin): Use inline variable instead after adopting C++17.
kProducers()48423   static constexpr FieldMetadata_Producers kProducers() { return {}; }
add_producers()48424   template <typename T = TraceConfig_ProducerConfig> T* add_producers() {
48425     return BeginNestedMessage<T>(6);
48426   }
48427 
48428 
48429   using FieldMetadata_StatsdMetadata =
48430     ::protozero::proto_utils::FieldMetadata<
48431       7,
48432       ::protozero::proto_utils::RepetitionType::kNotRepeated,
48433       ::protozero::proto_utils::ProtoSchemaType::kMessage,
48434       TraceConfig_StatsdMetadata,
48435       TraceConfig>;
48436 
48437   // Ceci n'est pas une pipe.
48438   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
48439   // type (and users are expected to use it as such, hence kCamelCase name).
48440   // It is declared as a function to keep protozero bindings header-only as
48441   // inline constexpr variables are not available until C++17 (while inline
48442   // functions are).
48443   // TODO(altimin): Use inline variable instead after adopting C++17.
kStatsdMetadata()48444   static constexpr FieldMetadata_StatsdMetadata kStatsdMetadata() { return {}; }
set_statsd_metadata()48445   template <typename T = TraceConfig_StatsdMetadata> T* set_statsd_metadata() {
48446     return BeginNestedMessage<T>(7);
48447   }
48448 
48449 
48450   using FieldMetadata_WriteIntoFile =
48451     ::protozero::proto_utils::FieldMetadata<
48452       8,
48453       ::protozero::proto_utils::RepetitionType::kNotRepeated,
48454       ::protozero::proto_utils::ProtoSchemaType::kBool,
48455       bool,
48456       TraceConfig>;
48457 
48458   // Ceci n'est pas une pipe.
48459   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
48460   // type (and users are expected to use it as such, hence kCamelCase name).
48461   // It is declared as a function to keep protozero bindings header-only as
48462   // inline constexpr variables are not available until C++17 (while inline
48463   // functions are).
48464   // TODO(altimin): Use inline variable instead after adopting C++17.
kWriteIntoFile()48465   static constexpr FieldMetadata_WriteIntoFile kWriteIntoFile() { return {}; }
set_write_into_file(bool value)48466   void set_write_into_file(bool value) {
48467     static constexpr uint32_t field_id = FieldMetadata_WriteIntoFile::kFieldId;
48468     // Call the appropriate protozero::Message::Append(field_id, ...)
48469     // method based on the type of the field.
48470     ::protozero::internal::FieldWriter<
48471       ::protozero::proto_utils::ProtoSchemaType::kBool>
48472         ::Append(*this, field_id, value);
48473   }
48474 
48475   using FieldMetadata_OutputPath =
48476     ::protozero::proto_utils::FieldMetadata<
48477       29,
48478       ::protozero::proto_utils::RepetitionType::kNotRepeated,
48479       ::protozero::proto_utils::ProtoSchemaType::kString,
48480       std::string,
48481       TraceConfig>;
48482 
48483   // Ceci n'est pas une pipe.
48484   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
48485   // type (and users are expected to use it as such, hence kCamelCase name).
48486   // It is declared as a function to keep protozero bindings header-only as
48487   // inline constexpr variables are not available until C++17 (while inline
48488   // functions are).
48489   // TODO(altimin): Use inline variable instead after adopting C++17.
kOutputPath()48490   static constexpr FieldMetadata_OutputPath kOutputPath() { return {}; }
set_output_path(const char * data,size_t size)48491   void set_output_path(const char* data, size_t size) {
48492     AppendBytes(FieldMetadata_OutputPath::kFieldId, data, size);
48493   }
set_output_path(std::string value)48494   void set_output_path(std::string value) {
48495     static constexpr uint32_t field_id = FieldMetadata_OutputPath::kFieldId;
48496     // Call the appropriate protozero::Message::Append(field_id, ...)
48497     // method based on the type of the field.
48498     ::protozero::internal::FieldWriter<
48499       ::protozero::proto_utils::ProtoSchemaType::kString>
48500         ::Append(*this, field_id, value);
48501   }
48502 
48503   using FieldMetadata_FileWritePeriodMs =
48504     ::protozero::proto_utils::FieldMetadata<
48505       9,
48506       ::protozero::proto_utils::RepetitionType::kNotRepeated,
48507       ::protozero::proto_utils::ProtoSchemaType::kUint32,
48508       uint32_t,
48509       TraceConfig>;
48510 
48511   // Ceci n'est pas une pipe.
48512   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
48513   // type (and users are expected to use it as such, hence kCamelCase name).
48514   // It is declared as a function to keep protozero bindings header-only as
48515   // inline constexpr variables are not available until C++17 (while inline
48516   // functions are).
48517   // TODO(altimin): Use inline variable instead after adopting C++17.
kFileWritePeriodMs()48518   static constexpr FieldMetadata_FileWritePeriodMs kFileWritePeriodMs() { return {}; }
set_file_write_period_ms(uint32_t value)48519   void set_file_write_period_ms(uint32_t value) {
48520     static constexpr uint32_t field_id = FieldMetadata_FileWritePeriodMs::kFieldId;
48521     // Call the appropriate protozero::Message::Append(field_id, ...)
48522     // method based on the type of the field.
48523     ::protozero::internal::FieldWriter<
48524       ::protozero::proto_utils::ProtoSchemaType::kUint32>
48525         ::Append(*this, field_id, value);
48526   }
48527 
48528   using FieldMetadata_MaxFileSizeBytes =
48529     ::protozero::proto_utils::FieldMetadata<
48530       10,
48531       ::protozero::proto_utils::RepetitionType::kNotRepeated,
48532       ::protozero::proto_utils::ProtoSchemaType::kUint64,
48533       uint64_t,
48534       TraceConfig>;
48535 
48536   // Ceci n'est pas une pipe.
48537   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
48538   // type (and users are expected to use it as such, hence kCamelCase name).
48539   // It is declared as a function to keep protozero bindings header-only as
48540   // inline constexpr variables are not available until C++17 (while inline
48541   // functions are).
48542   // TODO(altimin): Use inline variable instead after adopting C++17.
kMaxFileSizeBytes()48543   static constexpr FieldMetadata_MaxFileSizeBytes kMaxFileSizeBytes() { return {}; }
set_max_file_size_bytes(uint64_t value)48544   void set_max_file_size_bytes(uint64_t value) {
48545     static constexpr uint32_t field_id = FieldMetadata_MaxFileSizeBytes::kFieldId;
48546     // Call the appropriate protozero::Message::Append(field_id, ...)
48547     // method based on the type of the field.
48548     ::protozero::internal::FieldWriter<
48549       ::protozero::proto_utils::ProtoSchemaType::kUint64>
48550         ::Append(*this, field_id, value);
48551   }
48552 
48553   using FieldMetadata_GuardrailOverrides =
48554     ::protozero::proto_utils::FieldMetadata<
48555       11,
48556       ::protozero::proto_utils::RepetitionType::kNotRepeated,
48557       ::protozero::proto_utils::ProtoSchemaType::kMessage,
48558       TraceConfig_GuardrailOverrides,
48559       TraceConfig>;
48560 
48561   // Ceci n'est pas une pipe.
48562   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
48563   // type (and users are expected to use it as such, hence kCamelCase name).
48564   // It is declared as a function to keep protozero bindings header-only as
48565   // inline constexpr variables are not available until C++17 (while inline
48566   // functions are).
48567   // TODO(altimin): Use inline variable instead after adopting C++17.
kGuardrailOverrides()48568   static constexpr FieldMetadata_GuardrailOverrides kGuardrailOverrides() { return {}; }
set_guardrail_overrides()48569   template <typename T = TraceConfig_GuardrailOverrides> T* set_guardrail_overrides() {
48570     return BeginNestedMessage<T>(11);
48571   }
48572 
48573 
48574   using FieldMetadata_DeferredStart =
48575     ::protozero::proto_utils::FieldMetadata<
48576       12,
48577       ::protozero::proto_utils::RepetitionType::kNotRepeated,
48578       ::protozero::proto_utils::ProtoSchemaType::kBool,
48579       bool,
48580       TraceConfig>;
48581 
48582   // Ceci n'est pas une pipe.
48583   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
48584   // type (and users are expected to use it as such, hence kCamelCase name).
48585   // It is declared as a function to keep protozero bindings header-only as
48586   // inline constexpr variables are not available until C++17 (while inline
48587   // functions are).
48588   // TODO(altimin): Use inline variable instead after adopting C++17.
kDeferredStart()48589   static constexpr FieldMetadata_DeferredStart kDeferredStart() { return {}; }
set_deferred_start(bool value)48590   void set_deferred_start(bool value) {
48591     static constexpr uint32_t field_id = FieldMetadata_DeferredStart::kFieldId;
48592     // Call the appropriate protozero::Message::Append(field_id, ...)
48593     // method based on the type of the field.
48594     ::protozero::internal::FieldWriter<
48595       ::protozero::proto_utils::ProtoSchemaType::kBool>
48596         ::Append(*this, field_id, value);
48597   }
48598 
48599   using FieldMetadata_FlushPeriodMs =
48600     ::protozero::proto_utils::FieldMetadata<
48601       13,
48602       ::protozero::proto_utils::RepetitionType::kNotRepeated,
48603       ::protozero::proto_utils::ProtoSchemaType::kUint32,
48604       uint32_t,
48605       TraceConfig>;
48606 
48607   // Ceci n'est pas une pipe.
48608   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
48609   // type (and users are expected to use it as such, hence kCamelCase name).
48610   // It is declared as a function to keep protozero bindings header-only as
48611   // inline constexpr variables are not available until C++17 (while inline
48612   // functions are).
48613   // TODO(altimin): Use inline variable instead after adopting C++17.
kFlushPeriodMs()48614   static constexpr FieldMetadata_FlushPeriodMs kFlushPeriodMs() { return {}; }
set_flush_period_ms(uint32_t value)48615   void set_flush_period_ms(uint32_t value) {
48616     static constexpr uint32_t field_id = FieldMetadata_FlushPeriodMs::kFieldId;
48617     // Call the appropriate protozero::Message::Append(field_id, ...)
48618     // method based on the type of the field.
48619     ::protozero::internal::FieldWriter<
48620       ::protozero::proto_utils::ProtoSchemaType::kUint32>
48621         ::Append(*this, field_id, value);
48622   }
48623 
48624   using FieldMetadata_FlushTimeoutMs =
48625     ::protozero::proto_utils::FieldMetadata<
48626       14,
48627       ::protozero::proto_utils::RepetitionType::kNotRepeated,
48628       ::protozero::proto_utils::ProtoSchemaType::kUint32,
48629       uint32_t,
48630       TraceConfig>;
48631 
48632   // Ceci n'est pas une pipe.
48633   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
48634   // type (and users are expected to use it as such, hence kCamelCase name).
48635   // It is declared as a function to keep protozero bindings header-only as
48636   // inline constexpr variables are not available until C++17 (while inline
48637   // functions are).
48638   // TODO(altimin): Use inline variable instead after adopting C++17.
kFlushTimeoutMs()48639   static constexpr FieldMetadata_FlushTimeoutMs kFlushTimeoutMs() { return {}; }
set_flush_timeout_ms(uint32_t value)48640   void set_flush_timeout_ms(uint32_t value) {
48641     static constexpr uint32_t field_id = FieldMetadata_FlushTimeoutMs::kFieldId;
48642     // Call the appropriate protozero::Message::Append(field_id, ...)
48643     // method based on the type of the field.
48644     ::protozero::internal::FieldWriter<
48645       ::protozero::proto_utils::ProtoSchemaType::kUint32>
48646         ::Append(*this, field_id, value);
48647   }
48648 
48649   using FieldMetadata_DataSourceStopTimeoutMs =
48650     ::protozero::proto_utils::FieldMetadata<
48651       23,
48652       ::protozero::proto_utils::RepetitionType::kNotRepeated,
48653       ::protozero::proto_utils::ProtoSchemaType::kUint32,
48654       uint32_t,
48655       TraceConfig>;
48656 
48657   // Ceci n'est pas une pipe.
48658   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
48659   // type (and users are expected to use it as such, hence kCamelCase name).
48660   // It is declared as a function to keep protozero bindings header-only as
48661   // inline constexpr variables are not available until C++17 (while inline
48662   // functions are).
48663   // TODO(altimin): Use inline variable instead after adopting C++17.
kDataSourceStopTimeoutMs()48664   static constexpr FieldMetadata_DataSourceStopTimeoutMs kDataSourceStopTimeoutMs() { return {}; }
set_data_source_stop_timeout_ms(uint32_t value)48665   void set_data_source_stop_timeout_ms(uint32_t value) {
48666     static constexpr uint32_t field_id = FieldMetadata_DataSourceStopTimeoutMs::kFieldId;
48667     // Call the appropriate protozero::Message::Append(field_id, ...)
48668     // method based on the type of the field.
48669     ::protozero::internal::FieldWriter<
48670       ::protozero::proto_utils::ProtoSchemaType::kUint32>
48671         ::Append(*this, field_id, value);
48672   }
48673 
48674   using FieldMetadata_NotifyTraceur =
48675     ::protozero::proto_utils::FieldMetadata<
48676       16,
48677       ::protozero::proto_utils::RepetitionType::kNotRepeated,
48678       ::protozero::proto_utils::ProtoSchemaType::kBool,
48679       bool,
48680       TraceConfig>;
48681 
48682   // Ceci n'est pas une pipe.
48683   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
48684   // type (and users are expected to use it as such, hence kCamelCase name).
48685   // It is declared as a function to keep protozero bindings header-only as
48686   // inline constexpr variables are not available until C++17 (while inline
48687   // functions are).
48688   // TODO(altimin): Use inline variable instead after adopting C++17.
kNotifyTraceur()48689   static constexpr FieldMetadata_NotifyTraceur kNotifyTraceur() { return {}; }
set_notify_traceur(bool value)48690   void set_notify_traceur(bool value) {
48691     static constexpr uint32_t field_id = FieldMetadata_NotifyTraceur::kFieldId;
48692     // Call the appropriate protozero::Message::Append(field_id, ...)
48693     // method based on the type of the field.
48694     ::protozero::internal::FieldWriter<
48695       ::protozero::proto_utils::ProtoSchemaType::kBool>
48696         ::Append(*this, field_id, value);
48697   }
48698 
48699   using FieldMetadata_BugreportScore =
48700     ::protozero::proto_utils::FieldMetadata<
48701       30,
48702       ::protozero::proto_utils::RepetitionType::kNotRepeated,
48703       ::protozero::proto_utils::ProtoSchemaType::kInt32,
48704       int32_t,
48705       TraceConfig>;
48706 
48707   // Ceci n'est pas une pipe.
48708   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
48709   // type (and users are expected to use it as such, hence kCamelCase name).
48710   // It is declared as a function to keep protozero bindings header-only as
48711   // inline constexpr variables are not available until C++17 (while inline
48712   // functions are).
48713   // TODO(altimin): Use inline variable instead after adopting C++17.
kBugreportScore()48714   static constexpr FieldMetadata_BugreportScore kBugreportScore() { return {}; }
set_bugreport_score(int32_t value)48715   void set_bugreport_score(int32_t value) {
48716     static constexpr uint32_t field_id = FieldMetadata_BugreportScore::kFieldId;
48717     // Call the appropriate protozero::Message::Append(field_id, ...)
48718     // method based on the type of the field.
48719     ::protozero::internal::FieldWriter<
48720       ::protozero::proto_utils::ProtoSchemaType::kInt32>
48721         ::Append(*this, field_id, value);
48722   }
48723 
48724   using FieldMetadata_TriggerConfig =
48725     ::protozero::proto_utils::FieldMetadata<
48726       17,
48727       ::protozero::proto_utils::RepetitionType::kNotRepeated,
48728       ::protozero::proto_utils::ProtoSchemaType::kMessage,
48729       TraceConfig_TriggerConfig,
48730       TraceConfig>;
48731 
48732   // Ceci n'est pas une pipe.
48733   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
48734   // type (and users are expected to use it as such, hence kCamelCase name).
48735   // It is declared as a function to keep protozero bindings header-only as
48736   // inline constexpr variables are not available until C++17 (while inline
48737   // functions are).
48738   // TODO(altimin): Use inline variable instead after adopting C++17.
kTriggerConfig()48739   static constexpr FieldMetadata_TriggerConfig kTriggerConfig() { return {}; }
set_trigger_config()48740   template <typename T = TraceConfig_TriggerConfig> T* set_trigger_config() {
48741     return BeginNestedMessage<T>(17);
48742   }
48743 
48744 
48745   using FieldMetadata_ActivateTriggers =
48746     ::protozero::proto_utils::FieldMetadata<
48747       18,
48748       ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
48749       ::protozero::proto_utils::ProtoSchemaType::kString,
48750       std::string,
48751       TraceConfig>;
48752 
48753   // Ceci n'est pas une pipe.
48754   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
48755   // type (and users are expected to use it as such, hence kCamelCase name).
48756   // It is declared as a function to keep protozero bindings header-only as
48757   // inline constexpr variables are not available until C++17 (while inline
48758   // functions are).
48759   // TODO(altimin): Use inline variable instead after adopting C++17.
kActivateTriggers()48760   static constexpr FieldMetadata_ActivateTriggers kActivateTriggers() { return {}; }
add_activate_triggers(const char * data,size_t size)48761   void add_activate_triggers(const char* data, size_t size) {
48762     AppendBytes(FieldMetadata_ActivateTriggers::kFieldId, data, size);
48763   }
add_activate_triggers(std::string value)48764   void add_activate_triggers(std::string value) {
48765     static constexpr uint32_t field_id = FieldMetadata_ActivateTriggers::kFieldId;
48766     // Call the appropriate protozero::Message::Append(field_id, ...)
48767     // method based on the type of the field.
48768     ::protozero::internal::FieldWriter<
48769       ::protozero::proto_utils::ProtoSchemaType::kString>
48770         ::Append(*this, field_id, value);
48771   }
48772 
48773   using FieldMetadata_IncrementalStateConfig =
48774     ::protozero::proto_utils::FieldMetadata<
48775       21,
48776       ::protozero::proto_utils::RepetitionType::kNotRepeated,
48777       ::protozero::proto_utils::ProtoSchemaType::kMessage,
48778       TraceConfig_IncrementalStateConfig,
48779       TraceConfig>;
48780 
48781   // Ceci n'est pas une pipe.
48782   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
48783   // type (and users are expected to use it as such, hence kCamelCase name).
48784   // It is declared as a function to keep protozero bindings header-only as
48785   // inline constexpr variables are not available until C++17 (while inline
48786   // functions are).
48787   // TODO(altimin): Use inline variable instead after adopting C++17.
kIncrementalStateConfig()48788   static constexpr FieldMetadata_IncrementalStateConfig kIncrementalStateConfig() { return {}; }
set_incremental_state_config()48789   template <typename T = TraceConfig_IncrementalStateConfig> T* set_incremental_state_config() {
48790     return BeginNestedMessage<T>(21);
48791   }
48792 
48793 
48794   using FieldMetadata_AllowUserBuildTracing =
48795     ::protozero::proto_utils::FieldMetadata<
48796       19,
48797       ::protozero::proto_utils::RepetitionType::kNotRepeated,
48798       ::protozero::proto_utils::ProtoSchemaType::kBool,
48799       bool,
48800       TraceConfig>;
48801 
48802   // Ceci n'est pas une pipe.
48803   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
48804   // type (and users are expected to use it as such, hence kCamelCase name).
48805   // It is declared as a function to keep protozero bindings header-only as
48806   // inline constexpr variables are not available until C++17 (while inline
48807   // functions are).
48808   // TODO(altimin): Use inline variable instead after adopting C++17.
kAllowUserBuildTracing()48809   static constexpr FieldMetadata_AllowUserBuildTracing kAllowUserBuildTracing() { return {}; }
set_allow_user_build_tracing(bool value)48810   void set_allow_user_build_tracing(bool value) {
48811     static constexpr uint32_t field_id = FieldMetadata_AllowUserBuildTracing::kFieldId;
48812     // Call the appropriate protozero::Message::Append(field_id, ...)
48813     // method based on the type of the field.
48814     ::protozero::internal::FieldWriter<
48815       ::protozero::proto_utils::ProtoSchemaType::kBool>
48816         ::Append(*this, field_id, value);
48817   }
48818 
48819   using FieldMetadata_UniqueSessionName =
48820     ::protozero::proto_utils::FieldMetadata<
48821       22,
48822       ::protozero::proto_utils::RepetitionType::kNotRepeated,
48823       ::protozero::proto_utils::ProtoSchemaType::kString,
48824       std::string,
48825       TraceConfig>;
48826 
48827   // Ceci n'est pas une pipe.
48828   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
48829   // type (and users are expected to use it as such, hence kCamelCase name).
48830   // It is declared as a function to keep protozero bindings header-only as
48831   // inline constexpr variables are not available until C++17 (while inline
48832   // functions are).
48833   // TODO(altimin): Use inline variable instead after adopting C++17.
kUniqueSessionName()48834   static constexpr FieldMetadata_UniqueSessionName kUniqueSessionName() { return {}; }
set_unique_session_name(const char * data,size_t size)48835   void set_unique_session_name(const char* data, size_t size) {
48836     AppendBytes(FieldMetadata_UniqueSessionName::kFieldId, data, size);
48837   }
set_unique_session_name(std::string value)48838   void set_unique_session_name(std::string value) {
48839     static constexpr uint32_t field_id = FieldMetadata_UniqueSessionName::kFieldId;
48840     // Call the appropriate protozero::Message::Append(field_id, ...)
48841     // method based on the type of the field.
48842     ::protozero::internal::FieldWriter<
48843       ::protozero::proto_utils::ProtoSchemaType::kString>
48844         ::Append(*this, field_id, value);
48845   }
48846 
48847   using FieldMetadata_CompressionType =
48848     ::protozero::proto_utils::FieldMetadata<
48849       24,
48850       ::protozero::proto_utils::RepetitionType::kNotRepeated,
48851       ::protozero::proto_utils::ProtoSchemaType::kEnum,
48852       ::perfetto::protos::pbzero::TraceConfig_CompressionType,
48853       TraceConfig>;
48854 
48855   // Ceci n'est pas une pipe.
48856   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
48857   // type (and users are expected to use it as such, hence kCamelCase name).
48858   // It is declared as a function to keep protozero bindings header-only as
48859   // inline constexpr variables are not available until C++17 (while inline
48860   // functions are).
48861   // TODO(altimin): Use inline variable instead after adopting C++17.
kCompressionType()48862   static constexpr FieldMetadata_CompressionType kCompressionType() { return {}; }
set_compression_type(::perfetto::protos::pbzero::TraceConfig_CompressionType value)48863   void set_compression_type(::perfetto::protos::pbzero::TraceConfig_CompressionType value) {
48864     static constexpr uint32_t field_id = FieldMetadata_CompressionType::kFieldId;
48865     // Call the appropriate protozero::Message::Append(field_id, ...)
48866     // method based on the type of the field.
48867     ::protozero::internal::FieldWriter<
48868       ::protozero::proto_utils::ProtoSchemaType::kEnum>
48869         ::Append(*this, field_id, value);
48870   }
48871 
48872   using FieldMetadata_IncidentReportConfig =
48873     ::protozero::proto_utils::FieldMetadata<
48874       25,
48875       ::protozero::proto_utils::RepetitionType::kNotRepeated,
48876       ::protozero::proto_utils::ProtoSchemaType::kMessage,
48877       TraceConfig_IncidentReportConfig,
48878       TraceConfig>;
48879 
48880   // Ceci n'est pas une pipe.
48881   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
48882   // type (and users are expected to use it as such, hence kCamelCase name).
48883   // It is declared as a function to keep protozero bindings header-only as
48884   // inline constexpr variables are not available until C++17 (while inline
48885   // functions are).
48886   // TODO(altimin): Use inline variable instead after adopting C++17.
kIncidentReportConfig()48887   static constexpr FieldMetadata_IncidentReportConfig kIncidentReportConfig() { return {}; }
set_incident_report_config()48888   template <typename T = TraceConfig_IncidentReportConfig> T* set_incident_report_config() {
48889     return BeginNestedMessage<T>(25);
48890   }
48891 
48892 
48893   using FieldMetadata_StatsdLogging =
48894     ::protozero::proto_utils::FieldMetadata<
48895       31,
48896       ::protozero::proto_utils::RepetitionType::kNotRepeated,
48897       ::protozero::proto_utils::ProtoSchemaType::kEnum,
48898       ::perfetto::protos::pbzero::TraceConfig_StatsdLogging,
48899       TraceConfig>;
48900 
48901   // Ceci n'est pas une pipe.
48902   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
48903   // type (and users are expected to use it as such, hence kCamelCase name).
48904   // It is declared as a function to keep protozero bindings header-only as
48905   // inline constexpr variables are not available until C++17 (while inline
48906   // functions are).
48907   // TODO(altimin): Use inline variable instead after adopting C++17.
kStatsdLogging()48908   static constexpr FieldMetadata_StatsdLogging kStatsdLogging() { return {}; }
set_statsd_logging(::perfetto::protos::pbzero::TraceConfig_StatsdLogging value)48909   void set_statsd_logging(::perfetto::protos::pbzero::TraceConfig_StatsdLogging value) {
48910     static constexpr uint32_t field_id = FieldMetadata_StatsdLogging::kFieldId;
48911     // Call the appropriate protozero::Message::Append(field_id, ...)
48912     // method based on the type of the field.
48913     ::protozero::internal::FieldWriter<
48914       ::protozero::proto_utils::ProtoSchemaType::kEnum>
48915         ::Append(*this, field_id, value);
48916   }
48917 
48918   using FieldMetadata_TraceUuidMsb =
48919     ::protozero::proto_utils::FieldMetadata<
48920       27,
48921       ::protozero::proto_utils::RepetitionType::kNotRepeated,
48922       ::protozero::proto_utils::ProtoSchemaType::kInt64,
48923       int64_t,
48924       TraceConfig>;
48925 
48926   // Ceci n'est pas une pipe.
48927   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
48928   // type (and users are expected to use it as such, hence kCamelCase name).
48929   // It is declared as a function to keep protozero bindings header-only as
48930   // inline constexpr variables are not available until C++17 (while inline
48931   // functions are).
48932   // TODO(altimin): Use inline variable instead after adopting C++17.
kTraceUuidMsb()48933   static constexpr FieldMetadata_TraceUuidMsb kTraceUuidMsb() { return {}; }
set_trace_uuid_msb(int64_t value)48934   void set_trace_uuid_msb(int64_t value) {
48935     static constexpr uint32_t field_id = FieldMetadata_TraceUuidMsb::kFieldId;
48936     // Call the appropriate protozero::Message::Append(field_id, ...)
48937     // method based on the type of the field.
48938     ::protozero::internal::FieldWriter<
48939       ::protozero::proto_utils::ProtoSchemaType::kInt64>
48940         ::Append(*this, field_id, value);
48941   }
48942 
48943   using FieldMetadata_TraceUuidLsb =
48944     ::protozero::proto_utils::FieldMetadata<
48945       28,
48946       ::protozero::proto_utils::RepetitionType::kNotRepeated,
48947       ::protozero::proto_utils::ProtoSchemaType::kInt64,
48948       int64_t,
48949       TraceConfig>;
48950 
48951   // Ceci n'est pas une pipe.
48952   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
48953   // type (and users are expected to use it as such, hence kCamelCase name).
48954   // It is declared as a function to keep protozero bindings header-only as
48955   // inline constexpr variables are not available until C++17 (while inline
48956   // functions are).
48957   // TODO(altimin): Use inline variable instead after adopting C++17.
kTraceUuidLsb()48958   static constexpr FieldMetadata_TraceUuidLsb kTraceUuidLsb() { return {}; }
set_trace_uuid_lsb(int64_t value)48959   void set_trace_uuid_lsb(int64_t value) {
48960     static constexpr uint32_t field_id = FieldMetadata_TraceUuidLsb::kFieldId;
48961     // Call the appropriate protozero::Message::Append(field_id, ...)
48962     // method based on the type of the field.
48963     ::protozero::internal::FieldWriter<
48964       ::protozero::proto_utils::ProtoSchemaType::kInt64>
48965         ::Append(*this, field_id, value);
48966   }
48967 
48968   using FieldMetadata_TraceFilter =
48969     ::protozero::proto_utils::FieldMetadata<
48970       32,
48971       ::protozero::proto_utils::RepetitionType::kNotRepeated,
48972       ::protozero::proto_utils::ProtoSchemaType::kMessage,
48973       TraceConfig_TraceFilter,
48974       TraceConfig>;
48975 
48976   // Ceci n'est pas une pipe.
48977   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
48978   // type (and users are expected to use it as such, hence kCamelCase name).
48979   // It is declared as a function to keep protozero bindings header-only as
48980   // inline constexpr variables are not available until C++17 (while inline
48981   // functions are).
48982   // TODO(altimin): Use inline variable instead after adopting C++17.
kTraceFilter()48983   static constexpr FieldMetadata_TraceFilter kTraceFilter() { return {}; }
set_trace_filter()48984   template <typename T = TraceConfig_TraceFilter> T* set_trace_filter() {
48985     return BeginNestedMessage<T>(32);
48986   }
48987 
48988 };
48989 
48990 class TraceConfig_TraceFilter_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
48991  public:
TraceConfig_TraceFilter_Decoder(const uint8_t * data,size_t len)48992   TraceConfig_TraceFilter_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_TraceFilter_Decoder(const std::string & raw)48993   explicit TraceConfig_TraceFilter_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
TraceConfig_TraceFilter_Decoder(const::protozero::ConstBytes & raw)48994   explicit TraceConfig_TraceFilter_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_bytecode() const48995   bool has_bytecode() const { return at<1>().valid(); }
bytecode() const48996   ::protozero::ConstBytes bytecode() const { return at<1>().as_bytes(); }
48997 };
48998 
48999 class TraceConfig_TraceFilter : public ::protozero::Message {
49000  public:
49001   using Decoder = TraceConfig_TraceFilter_Decoder;
49002   enum : int32_t {
49003     kBytecodeFieldNumber = 1,
49004   };
49005 
49006   using FieldMetadata_Bytecode =
49007     ::protozero::proto_utils::FieldMetadata<
49008       1,
49009       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49010       ::protozero::proto_utils::ProtoSchemaType::kBytes,
49011       std::string,
49012       TraceConfig_TraceFilter>;
49013 
49014   // Ceci n'est pas une pipe.
49015   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49016   // type (and users are expected to use it as such, hence kCamelCase name).
49017   // It is declared as a function to keep protozero bindings header-only as
49018   // inline constexpr variables are not available until C++17 (while inline
49019   // functions are).
49020   // TODO(altimin): Use inline variable instead after adopting C++17.
kBytecode()49021   static constexpr FieldMetadata_Bytecode kBytecode() { return {}; }
set_bytecode(const uint8_t * data,size_t size)49022   void set_bytecode(const uint8_t* data, size_t size) {
49023     AppendBytes(FieldMetadata_Bytecode::kFieldId, data, size);
49024   }
set_bytecode(std::string value)49025   void set_bytecode(std::string value) {
49026     static constexpr uint32_t field_id = FieldMetadata_Bytecode::kFieldId;
49027     // Call the appropriate protozero::Message::Append(field_id, ...)
49028     // method based on the type of the field.
49029     ::protozero::internal::FieldWriter<
49030       ::protozero::proto_utils::ProtoSchemaType::kBytes>
49031         ::Append(*this, field_id, value);
49032   }
49033 };
49034 
49035 class TraceConfig_IncidentReportConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
49036  public:
TraceConfig_IncidentReportConfig_Decoder(const uint8_t * data,size_t len)49037   TraceConfig_IncidentReportConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_IncidentReportConfig_Decoder(const std::string & raw)49038   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)49039   explicit TraceConfig_IncidentReportConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_destination_package() const49040   bool has_destination_package() const { return at<1>().valid(); }
destination_package() const49041   ::protozero::ConstChars destination_package() const { return at<1>().as_string(); }
has_destination_class() const49042   bool has_destination_class() const { return at<2>().valid(); }
destination_class() const49043   ::protozero::ConstChars destination_class() const { return at<2>().as_string(); }
has_privacy_level() const49044   bool has_privacy_level() const { return at<3>().valid(); }
privacy_level() const49045   int32_t privacy_level() const { return at<3>().as_int32(); }
has_skip_incidentd() const49046   bool has_skip_incidentd() const { return at<5>().valid(); }
skip_incidentd() const49047   bool skip_incidentd() const { return at<5>().as_bool(); }
has_skip_dropbox() const49048   bool has_skip_dropbox() const { return at<4>().valid(); }
skip_dropbox() const49049   bool skip_dropbox() const { return at<4>().as_bool(); }
49050 };
49051 
49052 class TraceConfig_IncidentReportConfig : public ::protozero::Message {
49053  public:
49054   using Decoder = TraceConfig_IncidentReportConfig_Decoder;
49055   enum : int32_t {
49056     kDestinationPackageFieldNumber = 1,
49057     kDestinationClassFieldNumber = 2,
49058     kPrivacyLevelFieldNumber = 3,
49059     kSkipIncidentdFieldNumber = 5,
49060     kSkipDropboxFieldNumber = 4,
49061   };
49062 
49063   using FieldMetadata_DestinationPackage =
49064     ::protozero::proto_utils::FieldMetadata<
49065       1,
49066       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49067       ::protozero::proto_utils::ProtoSchemaType::kString,
49068       std::string,
49069       TraceConfig_IncidentReportConfig>;
49070 
49071   // Ceci n'est pas une pipe.
49072   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49073   // type (and users are expected to use it as such, hence kCamelCase name).
49074   // It is declared as a function to keep protozero bindings header-only as
49075   // inline constexpr variables are not available until C++17 (while inline
49076   // functions are).
49077   // TODO(altimin): Use inline variable instead after adopting C++17.
kDestinationPackage()49078   static constexpr FieldMetadata_DestinationPackage kDestinationPackage() { return {}; }
set_destination_package(const char * data,size_t size)49079   void set_destination_package(const char* data, size_t size) {
49080     AppendBytes(FieldMetadata_DestinationPackage::kFieldId, data, size);
49081   }
set_destination_package(std::string value)49082   void set_destination_package(std::string value) {
49083     static constexpr uint32_t field_id = FieldMetadata_DestinationPackage::kFieldId;
49084     // Call the appropriate protozero::Message::Append(field_id, ...)
49085     // method based on the type of the field.
49086     ::protozero::internal::FieldWriter<
49087       ::protozero::proto_utils::ProtoSchemaType::kString>
49088         ::Append(*this, field_id, value);
49089   }
49090 
49091   using FieldMetadata_DestinationClass =
49092     ::protozero::proto_utils::FieldMetadata<
49093       2,
49094       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49095       ::protozero::proto_utils::ProtoSchemaType::kString,
49096       std::string,
49097       TraceConfig_IncidentReportConfig>;
49098 
49099   // Ceci n'est pas une pipe.
49100   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49101   // type (and users are expected to use it as such, hence kCamelCase name).
49102   // It is declared as a function to keep protozero bindings header-only as
49103   // inline constexpr variables are not available until C++17 (while inline
49104   // functions are).
49105   // TODO(altimin): Use inline variable instead after adopting C++17.
kDestinationClass()49106   static constexpr FieldMetadata_DestinationClass kDestinationClass() { return {}; }
set_destination_class(const char * data,size_t size)49107   void set_destination_class(const char* data, size_t size) {
49108     AppendBytes(FieldMetadata_DestinationClass::kFieldId, data, size);
49109   }
set_destination_class(std::string value)49110   void set_destination_class(std::string value) {
49111     static constexpr uint32_t field_id = FieldMetadata_DestinationClass::kFieldId;
49112     // Call the appropriate protozero::Message::Append(field_id, ...)
49113     // method based on the type of the field.
49114     ::protozero::internal::FieldWriter<
49115       ::protozero::proto_utils::ProtoSchemaType::kString>
49116         ::Append(*this, field_id, value);
49117   }
49118 
49119   using FieldMetadata_PrivacyLevel =
49120     ::protozero::proto_utils::FieldMetadata<
49121       3,
49122       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49123       ::protozero::proto_utils::ProtoSchemaType::kInt32,
49124       int32_t,
49125       TraceConfig_IncidentReportConfig>;
49126 
49127   // Ceci n'est pas une pipe.
49128   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49129   // type (and users are expected to use it as such, hence kCamelCase name).
49130   // It is declared as a function to keep protozero bindings header-only as
49131   // inline constexpr variables are not available until C++17 (while inline
49132   // functions are).
49133   // TODO(altimin): Use inline variable instead after adopting C++17.
kPrivacyLevel()49134   static constexpr FieldMetadata_PrivacyLevel kPrivacyLevel() { return {}; }
set_privacy_level(int32_t value)49135   void set_privacy_level(int32_t value) {
49136     static constexpr uint32_t field_id = FieldMetadata_PrivacyLevel::kFieldId;
49137     // Call the appropriate protozero::Message::Append(field_id, ...)
49138     // method based on the type of the field.
49139     ::protozero::internal::FieldWriter<
49140       ::protozero::proto_utils::ProtoSchemaType::kInt32>
49141         ::Append(*this, field_id, value);
49142   }
49143 
49144   using FieldMetadata_SkipIncidentd =
49145     ::protozero::proto_utils::FieldMetadata<
49146       5,
49147       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49148       ::protozero::proto_utils::ProtoSchemaType::kBool,
49149       bool,
49150       TraceConfig_IncidentReportConfig>;
49151 
49152   // Ceci n'est pas une pipe.
49153   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49154   // type (and users are expected to use it as such, hence kCamelCase name).
49155   // It is declared as a function to keep protozero bindings header-only as
49156   // inline constexpr variables are not available until C++17 (while inline
49157   // functions are).
49158   // TODO(altimin): Use inline variable instead after adopting C++17.
kSkipIncidentd()49159   static constexpr FieldMetadata_SkipIncidentd kSkipIncidentd() { return {}; }
set_skip_incidentd(bool value)49160   void set_skip_incidentd(bool value) {
49161     static constexpr uint32_t field_id = FieldMetadata_SkipIncidentd::kFieldId;
49162     // Call the appropriate protozero::Message::Append(field_id, ...)
49163     // method based on the type of the field.
49164     ::protozero::internal::FieldWriter<
49165       ::protozero::proto_utils::ProtoSchemaType::kBool>
49166         ::Append(*this, field_id, value);
49167   }
49168 
49169   using FieldMetadata_SkipDropbox =
49170     ::protozero::proto_utils::FieldMetadata<
49171       4,
49172       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49173       ::protozero::proto_utils::ProtoSchemaType::kBool,
49174       bool,
49175       TraceConfig_IncidentReportConfig>;
49176 
49177   // Ceci n'est pas une pipe.
49178   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49179   // type (and users are expected to use it as such, hence kCamelCase name).
49180   // It is declared as a function to keep protozero bindings header-only as
49181   // inline constexpr variables are not available until C++17 (while inline
49182   // functions are).
49183   // TODO(altimin): Use inline variable instead after adopting C++17.
kSkipDropbox()49184   static constexpr FieldMetadata_SkipDropbox kSkipDropbox() { return {}; }
set_skip_dropbox(bool value)49185   void set_skip_dropbox(bool value) {
49186     static constexpr uint32_t field_id = FieldMetadata_SkipDropbox::kFieldId;
49187     // Call the appropriate protozero::Message::Append(field_id, ...)
49188     // method based on the type of the field.
49189     ::protozero::internal::FieldWriter<
49190       ::protozero::proto_utils::ProtoSchemaType::kBool>
49191         ::Append(*this, field_id, value);
49192   }
49193 };
49194 
49195 class TraceConfig_IncrementalStateConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
49196  public:
TraceConfig_IncrementalStateConfig_Decoder(const uint8_t * data,size_t len)49197   TraceConfig_IncrementalStateConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_IncrementalStateConfig_Decoder(const std::string & raw)49198   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)49199   explicit TraceConfig_IncrementalStateConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_clear_period_ms() const49200   bool has_clear_period_ms() const { return at<1>().valid(); }
clear_period_ms() const49201   uint32_t clear_period_ms() const { return at<1>().as_uint32(); }
49202 };
49203 
49204 class TraceConfig_IncrementalStateConfig : public ::protozero::Message {
49205  public:
49206   using Decoder = TraceConfig_IncrementalStateConfig_Decoder;
49207   enum : int32_t {
49208     kClearPeriodMsFieldNumber = 1,
49209   };
49210 
49211   using FieldMetadata_ClearPeriodMs =
49212     ::protozero::proto_utils::FieldMetadata<
49213       1,
49214       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49215       ::protozero::proto_utils::ProtoSchemaType::kUint32,
49216       uint32_t,
49217       TraceConfig_IncrementalStateConfig>;
49218 
49219   // Ceci n'est pas une pipe.
49220   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49221   // type (and users are expected to use it as such, hence kCamelCase name).
49222   // It is declared as a function to keep protozero bindings header-only as
49223   // inline constexpr variables are not available until C++17 (while inline
49224   // functions are).
49225   // TODO(altimin): Use inline variable instead after adopting C++17.
kClearPeriodMs()49226   static constexpr FieldMetadata_ClearPeriodMs kClearPeriodMs() { return {}; }
set_clear_period_ms(uint32_t value)49227   void set_clear_period_ms(uint32_t value) {
49228     static constexpr uint32_t field_id = FieldMetadata_ClearPeriodMs::kFieldId;
49229     // Call the appropriate protozero::Message::Append(field_id, ...)
49230     // method based on the type of the field.
49231     ::protozero::internal::FieldWriter<
49232       ::protozero::proto_utils::ProtoSchemaType::kUint32>
49233         ::Append(*this, field_id, value);
49234   }
49235 };
49236 
49237 class TraceConfig_TriggerConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
49238  public:
TraceConfig_TriggerConfig_Decoder(const uint8_t * data,size_t len)49239   TraceConfig_TriggerConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_TriggerConfig_Decoder(const std::string & raw)49240   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)49241   explicit TraceConfig_TriggerConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_trigger_mode() const49242   bool has_trigger_mode() const { return at<1>().valid(); }
trigger_mode() const49243   int32_t trigger_mode() const { return at<1>().as_int32(); }
has_triggers() const49244   bool has_triggers() const { return at<2>().valid(); }
triggers() const49245   ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> triggers() const { return GetRepeated<::protozero::ConstBytes>(2); }
has_trigger_timeout_ms() const49246   bool has_trigger_timeout_ms() const { return at<3>().valid(); }
trigger_timeout_ms() const49247   uint32_t trigger_timeout_ms() const { return at<3>().as_uint32(); }
49248 };
49249 
49250 class TraceConfig_TriggerConfig : public ::protozero::Message {
49251  public:
49252   using Decoder = TraceConfig_TriggerConfig_Decoder;
49253   enum : int32_t {
49254     kTriggerModeFieldNumber = 1,
49255     kTriggersFieldNumber = 2,
49256     kTriggerTimeoutMsFieldNumber = 3,
49257   };
49258   using Trigger = ::perfetto::protos::pbzero::TraceConfig_TriggerConfig_Trigger;
49259   using TriggerMode = ::perfetto::protos::pbzero::TraceConfig_TriggerConfig_TriggerMode;
49260   static const TriggerMode UNSPECIFIED = TraceConfig_TriggerConfig_TriggerMode_UNSPECIFIED;
49261   static const TriggerMode START_TRACING = TraceConfig_TriggerConfig_TriggerMode_START_TRACING;
49262   static const TriggerMode STOP_TRACING = TraceConfig_TriggerConfig_TriggerMode_STOP_TRACING;
49263 
49264   using FieldMetadata_TriggerMode =
49265     ::protozero::proto_utils::FieldMetadata<
49266       1,
49267       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49268       ::protozero::proto_utils::ProtoSchemaType::kEnum,
49269       ::perfetto::protos::pbzero::TraceConfig_TriggerConfig_TriggerMode,
49270       TraceConfig_TriggerConfig>;
49271 
49272   // Ceci n'est pas une pipe.
49273   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49274   // type (and users are expected to use it as such, hence kCamelCase name).
49275   // It is declared as a function to keep protozero bindings header-only as
49276   // inline constexpr variables are not available until C++17 (while inline
49277   // functions are).
49278   // TODO(altimin): Use inline variable instead after adopting C++17.
kTriggerMode()49279   static constexpr FieldMetadata_TriggerMode kTriggerMode() { return {}; }
set_trigger_mode(::perfetto::protos::pbzero::TraceConfig_TriggerConfig_TriggerMode value)49280   void set_trigger_mode(::perfetto::protos::pbzero::TraceConfig_TriggerConfig_TriggerMode value) {
49281     static constexpr uint32_t field_id = FieldMetadata_TriggerMode::kFieldId;
49282     // Call the appropriate protozero::Message::Append(field_id, ...)
49283     // method based on the type of the field.
49284     ::protozero::internal::FieldWriter<
49285       ::protozero::proto_utils::ProtoSchemaType::kEnum>
49286         ::Append(*this, field_id, value);
49287   }
49288 
49289   using FieldMetadata_Triggers =
49290     ::protozero::proto_utils::FieldMetadata<
49291       2,
49292       ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
49293       ::protozero::proto_utils::ProtoSchemaType::kMessage,
49294       TraceConfig_TriggerConfig_Trigger,
49295       TraceConfig_TriggerConfig>;
49296 
49297   // Ceci n'est pas une pipe.
49298   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49299   // type (and users are expected to use it as such, hence kCamelCase name).
49300   // It is declared as a function to keep protozero bindings header-only as
49301   // inline constexpr variables are not available until C++17 (while inline
49302   // functions are).
49303   // TODO(altimin): Use inline variable instead after adopting C++17.
kTriggers()49304   static constexpr FieldMetadata_Triggers kTriggers() { return {}; }
add_triggers()49305   template <typename T = TraceConfig_TriggerConfig_Trigger> T* add_triggers() {
49306     return BeginNestedMessage<T>(2);
49307   }
49308 
49309 
49310   using FieldMetadata_TriggerTimeoutMs =
49311     ::protozero::proto_utils::FieldMetadata<
49312       3,
49313       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49314       ::protozero::proto_utils::ProtoSchemaType::kUint32,
49315       uint32_t,
49316       TraceConfig_TriggerConfig>;
49317 
49318   // Ceci n'est pas une pipe.
49319   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49320   // type (and users are expected to use it as such, hence kCamelCase name).
49321   // It is declared as a function to keep protozero bindings header-only as
49322   // inline constexpr variables are not available until C++17 (while inline
49323   // functions are).
49324   // TODO(altimin): Use inline variable instead after adopting C++17.
kTriggerTimeoutMs()49325   static constexpr FieldMetadata_TriggerTimeoutMs kTriggerTimeoutMs() { return {}; }
set_trigger_timeout_ms(uint32_t value)49326   void set_trigger_timeout_ms(uint32_t value) {
49327     static constexpr uint32_t field_id = FieldMetadata_TriggerTimeoutMs::kFieldId;
49328     // Call the appropriate protozero::Message::Append(field_id, ...)
49329     // method based on the type of the field.
49330     ::protozero::internal::FieldWriter<
49331       ::protozero::proto_utils::ProtoSchemaType::kUint32>
49332         ::Append(*this, field_id, value);
49333   }
49334 };
49335 
49336 class TraceConfig_TriggerConfig_Trigger_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
49337  public:
TraceConfig_TriggerConfig_Trigger_Decoder(const uint8_t * data,size_t len)49338   TraceConfig_TriggerConfig_Trigger_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_TriggerConfig_Trigger_Decoder(const std::string & raw)49339   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)49340   explicit TraceConfig_TriggerConfig_Trigger_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_name() const49341   bool has_name() const { return at<1>().valid(); }
name() const49342   ::protozero::ConstChars name() const { return at<1>().as_string(); }
has_producer_name_regex() const49343   bool has_producer_name_regex() const { return at<2>().valid(); }
producer_name_regex() const49344   ::protozero::ConstChars producer_name_regex() const { return at<2>().as_string(); }
has_stop_delay_ms() const49345   bool has_stop_delay_ms() const { return at<3>().valid(); }
stop_delay_ms() const49346   uint32_t stop_delay_ms() const { return at<3>().as_uint32(); }
has_max_per_24_h() const49347   bool has_max_per_24_h() const { return at<4>().valid(); }
max_per_24_h() const49348   uint32_t max_per_24_h() const { return at<4>().as_uint32(); }
has_skip_probability() const49349   bool has_skip_probability() const { return at<5>().valid(); }
skip_probability() const49350   double skip_probability() const { return at<5>().as_double(); }
49351 };
49352 
49353 class TraceConfig_TriggerConfig_Trigger : public ::protozero::Message {
49354  public:
49355   using Decoder = TraceConfig_TriggerConfig_Trigger_Decoder;
49356   enum : int32_t {
49357     kNameFieldNumber = 1,
49358     kProducerNameRegexFieldNumber = 2,
49359     kStopDelayMsFieldNumber = 3,
49360     kMaxPer24HFieldNumber = 4,
49361     kSkipProbabilityFieldNumber = 5,
49362   };
49363 
49364   using FieldMetadata_Name =
49365     ::protozero::proto_utils::FieldMetadata<
49366       1,
49367       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49368       ::protozero::proto_utils::ProtoSchemaType::kString,
49369       std::string,
49370       TraceConfig_TriggerConfig_Trigger>;
49371 
49372   // Ceci n'est pas une pipe.
49373   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49374   // type (and users are expected to use it as such, hence kCamelCase name).
49375   // It is declared as a function to keep protozero bindings header-only as
49376   // inline constexpr variables are not available until C++17 (while inline
49377   // functions are).
49378   // TODO(altimin): Use inline variable instead after adopting C++17.
kName()49379   static constexpr FieldMetadata_Name kName() { return {}; }
set_name(const char * data,size_t size)49380   void set_name(const char* data, size_t size) {
49381     AppendBytes(FieldMetadata_Name::kFieldId, data, size);
49382   }
set_name(std::string value)49383   void set_name(std::string value) {
49384     static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
49385     // Call the appropriate protozero::Message::Append(field_id, ...)
49386     // method based on the type of the field.
49387     ::protozero::internal::FieldWriter<
49388       ::protozero::proto_utils::ProtoSchemaType::kString>
49389         ::Append(*this, field_id, value);
49390   }
49391 
49392   using FieldMetadata_ProducerNameRegex =
49393     ::protozero::proto_utils::FieldMetadata<
49394       2,
49395       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49396       ::protozero::proto_utils::ProtoSchemaType::kString,
49397       std::string,
49398       TraceConfig_TriggerConfig_Trigger>;
49399 
49400   // Ceci n'est pas une pipe.
49401   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49402   // type (and users are expected to use it as such, hence kCamelCase name).
49403   // It is declared as a function to keep protozero bindings header-only as
49404   // inline constexpr variables are not available until C++17 (while inline
49405   // functions are).
49406   // TODO(altimin): Use inline variable instead after adopting C++17.
kProducerNameRegex()49407   static constexpr FieldMetadata_ProducerNameRegex kProducerNameRegex() { return {}; }
set_producer_name_regex(const char * data,size_t size)49408   void set_producer_name_regex(const char* data, size_t size) {
49409     AppendBytes(FieldMetadata_ProducerNameRegex::kFieldId, data, size);
49410   }
set_producer_name_regex(std::string value)49411   void set_producer_name_regex(std::string value) {
49412     static constexpr uint32_t field_id = FieldMetadata_ProducerNameRegex::kFieldId;
49413     // Call the appropriate protozero::Message::Append(field_id, ...)
49414     // method based on the type of the field.
49415     ::protozero::internal::FieldWriter<
49416       ::protozero::proto_utils::ProtoSchemaType::kString>
49417         ::Append(*this, field_id, value);
49418   }
49419 
49420   using FieldMetadata_StopDelayMs =
49421     ::protozero::proto_utils::FieldMetadata<
49422       3,
49423       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49424       ::protozero::proto_utils::ProtoSchemaType::kUint32,
49425       uint32_t,
49426       TraceConfig_TriggerConfig_Trigger>;
49427 
49428   // Ceci n'est pas une pipe.
49429   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49430   // type (and users are expected to use it as such, hence kCamelCase name).
49431   // It is declared as a function to keep protozero bindings header-only as
49432   // inline constexpr variables are not available until C++17 (while inline
49433   // functions are).
49434   // TODO(altimin): Use inline variable instead after adopting C++17.
kStopDelayMs()49435   static constexpr FieldMetadata_StopDelayMs kStopDelayMs() { return {}; }
set_stop_delay_ms(uint32_t value)49436   void set_stop_delay_ms(uint32_t value) {
49437     static constexpr uint32_t field_id = FieldMetadata_StopDelayMs::kFieldId;
49438     // Call the appropriate protozero::Message::Append(field_id, ...)
49439     // method based on the type of the field.
49440     ::protozero::internal::FieldWriter<
49441       ::protozero::proto_utils::ProtoSchemaType::kUint32>
49442         ::Append(*this, field_id, value);
49443   }
49444 
49445   using FieldMetadata_MaxPer24H =
49446     ::protozero::proto_utils::FieldMetadata<
49447       4,
49448       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49449       ::protozero::proto_utils::ProtoSchemaType::kUint32,
49450       uint32_t,
49451       TraceConfig_TriggerConfig_Trigger>;
49452 
49453   // Ceci n'est pas une pipe.
49454   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49455   // type (and users are expected to use it as such, hence kCamelCase name).
49456   // It is declared as a function to keep protozero bindings header-only as
49457   // inline constexpr variables are not available until C++17 (while inline
49458   // functions are).
49459   // TODO(altimin): Use inline variable instead after adopting C++17.
kMaxPer24H()49460   static constexpr FieldMetadata_MaxPer24H kMaxPer24H() { return {}; }
set_max_per_24_h(uint32_t value)49461   void set_max_per_24_h(uint32_t value) {
49462     static constexpr uint32_t field_id = FieldMetadata_MaxPer24H::kFieldId;
49463     // Call the appropriate protozero::Message::Append(field_id, ...)
49464     // method based on the type of the field.
49465     ::protozero::internal::FieldWriter<
49466       ::protozero::proto_utils::ProtoSchemaType::kUint32>
49467         ::Append(*this, field_id, value);
49468   }
49469 
49470   using FieldMetadata_SkipProbability =
49471     ::protozero::proto_utils::FieldMetadata<
49472       5,
49473       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49474       ::protozero::proto_utils::ProtoSchemaType::kDouble,
49475       double,
49476       TraceConfig_TriggerConfig_Trigger>;
49477 
49478   // Ceci n'est pas une pipe.
49479   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49480   // type (and users are expected to use it as such, hence kCamelCase name).
49481   // It is declared as a function to keep protozero bindings header-only as
49482   // inline constexpr variables are not available until C++17 (while inline
49483   // functions are).
49484   // TODO(altimin): Use inline variable instead after adopting C++17.
kSkipProbability()49485   static constexpr FieldMetadata_SkipProbability kSkipProbability() { return {}; }
set_skip_probability(double value)49486   void set_skip_probability(double value) {
49487     static constexpr uint32_t field_id = FieldMetadata_SkipProbability::kFieldId;
49488     // Call the appropriate protozero::Message::Append(field_id, ...)
49489     // method based on the type of the field.
49490     ::protozero::internal::FieldWriter<
49491       ::protozero::proto_utils::ProtoSchemaType::kDouble>
49492         ::Append(*this, field_id, value);
49493   }
49494 };
49495 
49496 class TraceConfig_GuardrailOverrides_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
49497  public:
TraceConfig_GuardrailOverrides_Decoder(const uint8_t * data,size_t len)49498   TraceConfig_GuardrailOverrides_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_GuardrailOverrides_Decoder(const std::string & raw)49499   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)49500   explicit TraceConfig_GuardrailOverrides_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_max_upload_per_day_bytes() const49501   bool has_max_upload_per_day_bytes() const { return at<1>().valid(); }
max_upload_per_day_bytes() const49502   uint64_t max_upload_per_day_bytes() const { return at<1>().as_uint64(); }
49503 };
49504 
49505 class TraceConfig_GuardrailOverrides : public ::protozero::Message {
49506  public:
49507   using Decoder = TraceConfig_GuardrailOverrides_Decoder;
49508   enum : int32_t {
49509     kMaxUploadPerDayBytesFieldNumber = 1,
49510   };
49511 
49512   using FieldMetadata_MaxUploadPerDayBytes =
49513     ::protozero::proto_utils::FieldMetadata<
49514       1,
49515       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49516       ::protozero::proto_utils::ProtoSchemaType::kUint64,
49517       uint64_t,
49518       TraceConfig_GuardrailOverrides>;
49519 
49520   // Ceci n'est pas une pipe.
49521   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49522   // type (and users are expected to use it as such, hence kCamelCase name).
49523   // It is declared as a function to keep protozero bindings header-only as
49524   // inline constexpr variables are not available until C++17 (while inline
49525   // functions are).
49526   // TODO(altimin): Use inline variable instead after adopting C++17.
kMaxUploadPerDayBytes()49527   static constexpr FieldMetadata_MaxUploadPerDayBytes kMaxUploadPerDayBytes() { return {}; }
set_max_upload_per_day_bytes(uint64_t value)49528   void set_max_upload_per_day_bytes(uint64_t value) {
49529     static constexpr uint32_t field_id = FieldMetadata_MaxUploadPerDayBytes::kFieldId;
49530     // Call the appropriate protozero::Message::Append(field_id, ...)
49531     // method based on the type of the field.
49532     ::protozero::internal::FieldWriter<
49533       ::protozero::proto_utils::ProtoSchemaType::kUint64>
49534         ::Append(*this, field_id, value);
49535   }
49536 };
49537 
49538 class TraceConfig_StatsdMetadata_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
49539  public:
TraceConfig_StatsdMetadata_Decoder(const uint8_t * data,size_t len)49540   TraceConfig_StatsdMetadata_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_StatsdMetadata_Decoder(const std::string & raw)49541   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)49542   explicit TraceConfig_StatsdMetadata_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_triggering_alert_id() const49543   bool has_triggering_alert_id() const { return at<1>().valid(); }
triggering_alert_id() const49544   int64_t triggering_alert_id() const { return at<1>().as_int64(); }
has_triggering_config_uid() const49545   bool has_triggering_config_uid() const { return at<2>().valid(); }
triggering_config_uid() const49546   int32_t triggering_config_uid() const { return at<2>().as_int32(); }
has_triggering_config_id() const49547   bool has_triggering_config_id() const { return at<3>().valid(); }
triggering_config_id() const49548   int64_t triggering_config_id() const { return at<3>().as_int64(); }
has_triggering_subscription_id() const49549   bool has_triggering_subscription_id() const { return at<4>().valid(); }
triggering_subscription_id() const49550   int64_t triggering_subscription_id() const { return at<4>().as_int64(); }
49551 };
49552 
49553 class TraceConfig_StatsdMetadata : public ::protozero::Message {
49554  public:
49555   using Decoder = TraceConfig_StatsdMetadata_Decoder;
49556   enum : int32_t {
49557     kTriggeringAlertIdFieldNumber = 1,
49558     kTriggeringConfigUidFieldNumber = 2,
49559     kTriggeringConfigIdFieldNumber = 3,
49560     kTriggeringSubscriptionIdFieldNumber = 4,
49561   };
49562 
49563   using FieldMetadata_TriggeringAlertId =
49564     ::protozero::proto_utils::FieldMetadata<
49565       1,
49566       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49567       ::protozero::proto_utils::ProtoSchemaType::kInt64,
49568       int64_t,
49569       TraceConfig_StatsdMetadata>;
49570 
49571   // Ceci n'est pas une pipe.
49572   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49573   // type (and users are expected to use it as such, hence kCamelCase name).
49574   // It is declared as a function to keep protozero bindings header-only as
49575   // inline constexpr variables are not available until C++17 (while inline
49576   // functions are).
49577   // TODO(altimin): Use inline variable instead after adopting C++17.
kTriggeringAlertId()49578   static constexpr FieldMetadata_TriggeringAlertId kTriggeringAlertId() { return {}; }
set_triggering_alert_id(int64_t value)49579   void set_triggering_alert_id(int64_t value) {
49580     static constexpr uint32_t field_id = FieldMetadata_TriggeringAlertId::kFieldId;
49581     // Call the appropriate protozero::Message::Append(field_id, ...)
49582     // method based on the type of the field.
49583     ::protozero::internal::FieldWriter<
49584       ::protozero::proto_utils::ProtoSchemaType::kInt64>
49585         ::Append(*this, field_id, value);
49586   }
49587 
49588   using FieldMetadata_TriggeringConfigUid =
49589     ::protozero::proto_utils::FieldMetadata<
49590       2,
49591       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49592       ::protozero::proto_utils::ProtoSchemaType::kInt32,
49593       int32_t,
49594       TraceConfig_StatsdMetadata>;
49595 
49596   // Ceci n'est pas une pipe.
49597   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49598   // type (and users are expected to use it as such, hence kCamelCase name).
49599   // It is declared as a function to keep protozero bindings header-only as
49600   // inline constexpr variables are not available until C++17 (while inline
49601   // functions are).
49602   // TODO(altimin): Use inline variable instead after adopting C++17.
kTriggeringConfigUid()49603   static constexpr FieldMetadata_TriggeringConfigUid kTriggeringConfigUid() { return {}; }
set_triggering_config_uid(int32_t value)49604   void set_triggering_config_uid(int32_t value) {
49605     static constexpr uint32_t field_id = FieldMetadata_TriggeringConfigUid::kFieldId;
49606     // Call the appropriate protozero::Message::Append(field_id, ...)
49607     // method based on the type of the field.
49608     ::protozero::internal::FieldWriter<
49609       ::protozero::proto_utils::ProtoSchemaType::kInt32>
49610         ::Append(*this, field_id, value);
49611   }
49612 
49613   using FieldMetadata_TriggeringConfigId =
49614     ::protozero::proto_utils::FieldMetadata<
49615       3,
49616       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49617       ::protozero::proto_utils::ProtoSchemaType::kInt64,
49618       int64_t,
49619       TraceConfig_StatsdMetadata>;
49620 
49621   // Ceci n'est pas une pipe.
49622   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49623   // type (and users are expected to use it as such, hence kCamelCase name).
49624   // It is declared as a function to keep protozero bindings header-only as
49625   // inline constexpr variables are not available until C++17 (while inline
49626   // functions are).
49627   // TODO(altimin): Use inline variable instead after adopting C++17.
kTriggeringConfigId()49628   static constexpr FieldMetadata_TriggeringConfigId kTriggeringConfigId() { return {}; }
set_triggering_config_id(int64_t value)49629   void set_triggering_config_id(int64_t value) {
49630     static constexpr uint32_t field_id = FieldMetadata_TriggeringConfigId::kFieldId;
49631     // Call the appropriate protozero::Message::Append(field_id, ...)
49632     // method based on the type of the field.
49633     ::protozero::internal::FieldWriter<
49634       ::protozero::proto_utils::ProtoSchemaType::kInt64>
49635         ::Append(*this, field_id, value);
49636   }
49637 
49638   using FieldMetadata_TriggeringSubscriptionId =
49639     ::protozero::proto_utils::FieldMetadata<
49640       4,
49641       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49642       ::protozero::proto_utils::ProtoSchemaType::kInt64,
49643       int64_t,
49644       TraceConfig_StatsdMetadata>;
49645 
49646   // Ceci n'est pas une pipe.
49647   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49648   // type (and users are expected to use it as such, hence kCamelCase name).
49649   // It is declared as a function to keep protozero bindings header-only as
49650   // inline constexpr variables are not available until C++17 (while inline
49651   // functions are).
49652   // TODO(altimin): Use inline variable instead after adopting C++17.
kTriggeringSubscriptionId()49653   static constexpr FieldMetadata_TriggeringSubscriptionId kTriggeringSubscriptionId() { return {}; }
set_triggering_subscription_id(int64_t value)49654   void set_triggering_subscription_id(int64_t value) {
49655     static constexpr uint32_t field_id = FieldMetadata_TriggeringSubscriptionId::kFieldId;
49656     // Call the appropriate protozero::Message::Append(field_id, ...)
49657     // method based on the type of the field.
49658     ::protozero::internal::FieldWriter<
49659       ::protozero::proto_utils::ProtoSchemaType::kInt64>
49660         ::Append(*this, field_id, value);
49661   }
49662 };
49663 
49664 class TraceConfig_ProducerConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
49665  public:
TraceConfig_ProducerConfig_Decoder(const uint8_t * data,size_t len)49666   TraceConfig_ProducerConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_ProducerConfig_Decoder(const std::string & raw)49667   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)49668   explicit TraceConfig_ProducerConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_producer_name() const49669   bool has_producer_name() const { return at<1>().valid(); }
producer_name() const49670   ::protozero::ConstChars producer_name() const { return at<1>().as_string(); }
has_shm_size_kb() const49671   bool has_shm_size_kb() const { return at<2>().valid(); }
shm_size_kb() const49672   uint32_t shm_size_kb() const { return at<2>().as_uint32(); }
has_page_size_kb() const49673   bool has_page_size_kb() const { return at<3>().valid(); }
page_size_kb() const49674   uint32_t page_size_kb() const { return at<3>().as_uint32(); }
49675 };
49676 
49677 class TraceConfig_ProducerConfig : public ::protozero::Message {
49678  public:
49679   using Decoder = TraceConfig_ProducerConfig_Decoder;
49680   enum : int32_t {
49681     kProducerNameFieldNumber = 1,
49682     kShmSizeKbFieldNumber = 2,
49683     kPageSizeKbFieldNumber = 3,
49684   };
49685 
49686   using FieldMetadata_ProducerName =
49687     ::protozero::proto_utils::FieldMetadata<
49688       1,
49689       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49690       ::protozero::proto_utils::ProtoSchemaType::kString,
49691       std::string,
49692       TraceConfig_ProducerConfig>;
49693 
49694   // Ceci n'est pas une pipe.
49695   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49696   // type (and users are expected to use it as such, hence kCamelCase name).
49697   // It is declared as a function to keep protozero bindings header-only as
49698   // inline constexpr variables are not available until C++17 (while inline
49699   // functions are).
49700   // TODO(altimin): Use inline variable instead after adopting C++17.
kProducerName()49701   static constexpr FieldMetadata_ProducerName kProducerName() { return {}; }
set_producer_name(const char * data,size_t size)49702   void set_producer_name(const char* data, size_t size) {
49703     AppendBytes(FieldMetadata_ProducerName::kFieldId, data, size);
49704   }
set_producer_name(std::string value)49705   void set_producer_name(std::string value) {
49706     static constexpr uint32_t field_id = FieldMetadata_ProducerName::kFieldId;
49707     // Call the appropriate protozero::Message::Append(field_id, ...)
49708     // method based on the type of the field.
49709     ::protozero::internal::FieldWriter<
49710       ::protozero::proto_utils::ProtoSchemaType::kString>
49711         ::Append(*this, field_id, value);
49712   }
49713 
49714   using FieldMetadata_ShmSizeKb =
49715     ::protozero::proto_utils::FieldMetadata<
49716       2,
49717       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49718       ::protozero::proto_utils::ProtoSchemaType::kUint32,
49719       uint32_t,
49720       TraceConfig_ProducerConfig>;
49721 
49722   // Ceci n'est pas une pipe.
49723   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49724   // type (and users are expected to use it as such, hence kCamelCase name).
49725   // It is declared as a function to keep protozero bindings header-only as
49726   // inline constexpr variables are not available until C++17 (while inline
49727   // functions are).
49728   // TODO(altimin): Use inline variable instead after adopting C++17.
kShmSizeKb()49729   static constexpr FieldMetadata_ShmSizeKb kShmSizeKb() { return {}; }
set_shm_size_kb(uint32_t value)49730   void set_shm_size_kb(uint32_t value) {
49731     static constexpr uint32_t field_id = FieldMetadata_ShmSizeKb::kFieldId;
49732     // Call the appropriate protozero::Message::Append(field_id, ...)
49733     // method based on the type of the field.
49734     ::protozero::internal::FieldWriter<
49735       ::protozero::proto_utils::ProtoSchemaType::kUint32>
49736         ::Append(*this, field_id, value);
49737   }
49738 
49739   using FieldMetadata_PageSizeKb =
49740     ::protozero::proto_utils::FieldMetadata<
49741       3,
49742       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49743       ::protozero::proto_utils::ProtoSchemaType::kUint32,
49744       uint32_t,
49745       TraceConfig_ProducerConfig>;
49746 
49747   // Ceci n'est pas une pipe.
49748   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49749   // type (and users are expected to use it as such, hence kCamelCase name).
49750   // It is declared as a function to keep protozero bindings header-only as
49751   // inline constexpr variables are not available until C++17 (while inline
49752   // functions are).
49753   // TODO(altimin): Use inline variable instead after adopting C++17.
kPageSizeKb()49754   static constexpr FieldMetadata_PageSizeKb kPageSizeKb() { return {}; }
set_page_size_kb(uint32_t value)49755   void set_page_size_kb(uint32_t value) {
49756     static constexpr uint32_t field_id = FieldMetadata_PageSizeKb::kFieldId;
49757     // Call the appropriate protozero::Message::Append(field_id, ...)
49758     // method based on the type of the field.
49759     ::protozero::internal::FieldWriter<
49760       ::protozero::proto_utils::ProtoSchemaType::kUint32>
49761         ::Append(*this, field_id, value);
49762   }
49763 };
49764 
49765 class TraceConfig_BuiltinDataSource_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
49766  public:
TraceConfig_BuiltinDataSource_Decoder(const uint8_t * data,size_t len)49767   TraceConfig_BuiltinDataSource_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_BuiltinDataSource_Decoder(const std::string & raw)49768   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)49769   explicit TraceConfig_BuiltinDataSource_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_disable_clock_snapshotting() const49770   bool has_disable_clock_snapshotting() const { return at<1>().valid(); }
disable_clock_snapshotting() const49771   bool disable_clock_snapshotting() const { return at<1>().as_bool(); }
has_disable_trace_config() const49772   bool has_disable_trace_config() const { return at<2>().valid(); }
disable_trace_config() const49773   bool disable_trace_config() const { return at<2>().as_bool(); }
has_disable_system_info() const49774   bool has_disable_system_info() const { return at<3>().valid(); }
disable_system_info() const49775   bool disable_system_info() const { return at<3>().as_bool(); }
has_disable_service_events() const49776   bool has_disable_service_events() const { return at<4>().valid(); }
disable_service_events() const49777   bool disable_service_events() const { return at<4>().as_bool(); }
has_primary_trace_clock() const49778   bool has_primary_trace_clock() const { return at<5>().valid(); }
primary_trace_clock() const49779   int32_t primary_trace_clock() const { return at<5>().as_int32(); }
has_snapshot_interval_ms() const49780   bool has_snapshot_interval_ms() const { return at<6>().valid(); }
snapshot_interval_ms() const49781   uint32_t snapshot_interval_ms() const { return at<6>().as_uint32(); }
has_prefer_suspend_clock_for_snapshot() const49782   bool has_prefer_suspend_clock_for_snapshot() const { return at<7>().valid(); }
prefer_suspend_clock_for_snapshot() const49783   bool prefer_suspend_clock_for_snapshot() const { return at<7>().as_bool(); }
49784 };
49785 
49786 class TraceConfig_BuiltinDataSource : public ::protozero::Message {
49787  public:
49788   using Decoder = TraceConfig_BuiltinDataSource_Decoder;
49789   enum : int32_t {
49790     kDisableClockSnapshottingFieldNumber = 1,
49791     kDisableTraceConfigFieldNumber = 2,
49792     kDisableSystemInfoFieldNumber = 3,
49793     kDisableServiceEventsFieldNumber = 4,
49794     kPrimaryTraceClockFieldNumber = 5,
49795     kSnapshotIntervalMsFieldNumber = 6,
49796     kPreferSuspendClockForSnapshotFieldNumber = 7,
49797   };
49798 
49799   using FieldMetadata_DisableClockSnapshotting =
49800     ::protozero::proto_utils::FieldMetadata<
49801       1,
49802       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49803       ::protozero::proto_utils::ProtoSchemaType::kBool,
49804       bool,
49805       TraceConfig_BuiltinDataSource>;
49806 
49807   // Ceci n'est pas une pipe.
49808   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49809   // type (and users are expected to use it as such, hence kCamelCase name).
49810   // It is declared as a function to keep protozero bindings header-only as
49811   // inline constexpr variables are not available until C++17 (while inline
49812   // functions are).
49813   // TODO(altimin): Use inline variable instead after adopting C++17.
kDisableClockSnapshotting()49814   static constexpr FieldMetadata_DisableClockSnapshotting kDisableClockSnapshotting() { return {}; }
set_disable_clock_snapshotting(bool value)49815   void set_disable_clock_snapshotting(bool value) {
49816     static constexpr uint32_t field_id = FieldMetadata_DisableClockSnapshotting::kFieldId;
49817     // Call the appropriate protozero::Message::Append(field_id, ...)
49818     // method based on the type of the field.
49819     ::protozero::internal::FieldWriter<
49820       ::protozero::proto_utils::ProtoSchemaType::kBool>
49821         ::Append(*this, field_id, value);
49822   }
49823 
49824   using FieldMetadata_DisableTraceConfig =
49825     ::protozero::proto_utils::FieldMetadata<
49826       2,
49827       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49828       ::protozero::proto_utils::ProtoSchemaType::kBool,
49829       bool,
49830       TraceConfig_BuiltinDataSource>;
49831 
49832   // Ceci n'est pas une pipe.
49833   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49834   // type (and users are expected to use it as such, hence kCamelCase name).
49835   // It is declared as a function to keep protozero bindings header-only as
49836   // inline constexpr variables are not available until C++17 (while inline
49837   // functions are).
49838   // TODO(altimin): Use inline variable instead after adopting C++17.
kDisableTraceConfig()49839   static constexpr FieldMetadata_DisableTraceConfig kDisableTraceConfig() { return {}; }
set_disable_trace_config(bool value)49840   void set_disable_trace_config(bool value) {
49841     static constexpr uint32_t field_id = FieldMetadata_DisableTraceConfig::kFieldId;
49842     // Call the appropriate protozero::Message::Append(field_id, ...)
49843     // method based on the type of the field.
49844     ::protozero::internal::FieldWriter<
49845       ::protozero::proto_utils::ProtoSchemaType::kBool>
49846         ::Append(*this, field_id, value);
49847   }
49848 
49849   using FieldMetadata_DisableSystemInfo =
49850     ::protozero::proto_utils::FieldMetadata<
49851       3,
49852       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49853       ::protozero::proto_utils::ProtoSchemaType::kBool,
49854       bool,
49855       TraceConfig_BuiltinDataSource>;
49856 
49857   // Ceci n'est pas une pipe.
49858   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49859   // type (and users are expected to use it as such, hence kCamelCase name).
49860   // It is declared as a function to keep protozero bindings header-only as
49861   // inline constexpr variables are not available until C++17 (while inline
49862   // functions are).
49863   // TODO(altimin): Use inline variable instead after adopting C++17.
kDisableSystemInfo()49864   static constexpr FieldMetadata_DisableSystemInfo kDisableSystemInfo() { return {}; }
set_disable_system_info(bool value)49865   void set_disable_system_info(bool value) {
49866     static constexpr uint32_t field_id = FieldMetadata_DisableSystemInfo::kFieldId;
49867     // Call the appropriate protozero::Message::Append(field_id, ...)
49868     // method based on the type of the field.
49869     ::protozero::internal::FieldWriter<
49870       ::protozero::proto_utils::ProtoSchemaType::kBool>
49871         ::Append(*this, field_id, value);
49872   }
49873 
49874   using FieldMetadata_DisableServiceEvents =
49875     ::protozero::proto_utils::FieldMetadata<
49876       4,
49877       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49878       ::protozero::proto_utils::ProtoSchemaType::kBool,
49879       bool,
49880       TraceConfig_BuiltinDataSource>;
49881 
49882   // Ceci n'est pas une pipe.
49883   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49884   // type (and users are expected to use it as such, hence kCamelCase name).
49885   // It is declared as a function to keep protozero bindings header-only as
49886   // inline constexpr variables are not available until C++17 (while inline
49887   // functions are).
49888   // TODO(altimin): Use inline variable instead after adopting C++17.
kDisableServiceEvents()49889   static constexpr FieldMetadata_DisableServiceEvents kDisableServiceEvents() { return {}; }
set_disable_service_events(bool value)49890   void set_disable_service_events(bool value) {
49891     static constexpr uint32_t field_id = FieldMetadata_DisableServiceEvents::kFieldId;
49892     // Call the appropriate protozero::Message::Append(field_id, ...)
49893     // method based on the type of the field.
49894     ::protozero::internal::FieldWriter<
49895       ::protozero::proto_utils::ProtoSchemaType::kBool>
49896         ::Append(*this, field_id, value);
49897   }
49898 
49899   using FieldMetadata_PrimaryTraceClock =
49900     ::protozero::proto_utils::FieldMetadata<
49901       5,
49902       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49903       ::protozero::proto_utils::ProtoSchemaType::kEnum,
49904       ::perfetto::protos::pbzero::BuiltinClock,
49905       TraceConfig_BuiltinDataSource>;
49906 
49907   // Ceci n'est pas une pipe.
49908   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49909   // type (and users are expected to use it as such, hence kCamelCase name).
49910   // It is declared as a function to keep protozero bindings header-only as
49911   // inline constexpr variables are not available until C++17 (while inline
49912   // functions are).
49913   // TODO(altimin): Use inline variable instead after adopting C++17.
kPrimaryTraceClock()49914   static constexpr FieldMetadata_PrimaryTraceClock kPrimaryTraceClock() { return {}; }
set_primary_trace_clock(::perfetto::protos::pbzero::BuiltinClock value)49915   void set_primary_trace_clock(::perfetto::protos::pbzero::BuiltinClock value) {
49916     static constexpr uint32_t field_id = FieldMetadata_PrimaryTraceClock::kFieldId;
49917     // Call the appropriate protozero::Message::Append(field_id, ...)
49918     // method based on the type of the field.
49919     ::protozero::internal::FieldWriter<
49920       ::protozero::proto_utils::ProtoSchemaType::kEnum>
49921         ::Append(*this, field_id, value);
49922   }
49923 
49924   using FieldMetadata_SnapshotIntervalMs =
49925     ::protozero::proto_utils::FieldMetadata<
49926       6,
49927       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49928       ::protozero::proto_utils::ProtoSchemaType::kUint32,
49929       uint32_t,
49930       TraceConfig_BuiltinDataSource>;
49931 
49932   // Ceci n'est pas une pipe.
49933   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49934   // type (and users are expected to use it as such, hence kCamelCase name).
49935   // It is declared as a function to keep protozero bindings header-only as
49936   // inline constexpr variables are not available until C++17 (while inline
49937   // functions are).
49938   // TODO(altimin): Use inline variable instead after adopting C++17.
kSnapshotIntervalMs()49939   static constexpr FieldMetadata_SnapshotIntervalMs kSnapshotIntervalMs() { return {}; }
set_snapshot_interval_ms(uint32_t value)49940   void set_snapshot_interval_ms(uint32_t value) {
49941     static constexpr uint32_t field_id = FieldMetadata_SnapshotIntervalMs::kFieldId;
49942     // Call the appropriate protozero::Message::Append(field_id, ...)
49943     // method based on the type of the field.
49944     ::protozero::internal::FieldWriter<
49945       ::protozero::proto_utils::ProtoSchemaType::kUint32>
49946         ::Append(*this, field_id, value);
49947   }
49948 
49949   using FieldMetadata_PreferSuspendClockForSnapshot =
49950     ::protozero::proto_utils::FieldMetadata<
49951       7,
49952       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49953       ::protozero::proto_utils::ProtoSchemaType::kBool,
49954       bool,
49955       TraceConfig_BuiltinDataSource>;
49956 
49957   // Ceci n'est pas une pipe.
49958   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49959   // type (and users are expected to use it as such, hence kCamelCase name).
49960   // It is declared as a function to keep protozero bindings header-only as
49961   // inline constexpr variables are not available until C++17 (while inline
49962   // functions are).
49963   // TODO(altimin): Use inline variable instead after adopting C++17.
kPreferSuspendClockForSnapshot()49964   static constexpr FieldMetadata_PreferSuspendClockForSnapshot kPreferSuspendClockForSnapshot() { return {}; }
set_prefer_suspend_clock_for_snapshot(bool value)49965   void set_prefer_suspend_clock_for_snapshot(bool value) {
49966     static constexpr uint32_t field_id = FieldMetadata_PreferSuspendClockForSnapshot::kFieldId;
49967     // Call the appropriate protozero::Message::Append(field_id, ...)
49968     // method based on the type of the field.
49969     ::protozero::internal::FieldWriter<
49970       ::protozero::proto_utils::ProtoSchemaType::kBool>
49971         ::Append(*this, field_id, value);
49972   }
49973 };
49974 
49975 class TraceConfig_DataSource_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
49976  public:
TraceConfig_DataSource_Decoder(const uint8_t * data,size_t len)49977   TraceConfig_DataSource_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_DataSource_Decoder(const std::string & raw)49978   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)49979   explicit TraceConfig_DataSource_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_config() const49980   bool has_config() const { return at<1>().valid(); }
config() const49981   ::protozero::ConstBytes config() const { return at<1>().as_bytes(); }
has_producer_name_filter() const49982   bool has_producer_name_filter() const { return at<2>().valid(); }
producer_name_filter() const49983   ::protozero::RepeatedFieldIterator<::protozero::ConstChars> producer_name_filter() const { return GetRepeated<::protozero::ConstChars>(2); }
has_producer_name_regex_filter() const49984   bool has_producer_name_regex_filter() const { return at<3>().valid(); }
producer_name_regex_filter() const49985   ::protozero::RepeatedFieldIterator<::protozero::ConstChars> producer_name_regex_filter() const { return GetRepeated<::protozero::ConstChars>(3); }
49986 };
49987 
49988 class TraceConfig_DataSource : public ::protozero::Message {
49989  public:
49990   using Decoder = TraceConfig_DataSource_Decoder;
49991   enum : int32_t {
49992     kConfigFieldNumber = 1,
49993     kProducerNameFilterFieldNumber = 2,
49994     kProducerNameRegexFilterFieldNumber = 3,
49995   };
49996 
49997   using FieldMetadata_Config =
49998     ::protozero::proto_utils::FieldMetadata<
49999       1,
50000       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50001       ::protozero::proto_utils::ProtoSchemaType::kMessage,
50002       DataSourceConfig,
50003       TraceConfig_DataSource>;
50004 
50005   // Ceci n'est pas une pipe.
50006   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50007   // type (and users are expected to use it as such, hence kCamelCase name).
50008   // It is declared as a function to keep protozero bindings header-only as
50009   // inline constexpr variables are not available until C++17 (while inline
50010   // functions are).
50011   // TODO(altimin): Use inline variable instead after adopting C++17.
kConfig()50012   static constexpr FieldMetadata_Config kConfig() { return {}; }
set_config()50013   template <typename T = DataSourceConfig> T* set_config() {
50014     return BeginNestedMessage<T>(1);
50015   }
50016 
50017 
50018   using FieldMetadata_ProducerNameFilter =
50019     ::protozero::proto_utils::FieldMetadata<
50020       2,
50021       ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
50022       ::protozero::proto_utils::ProtoSchemaType::kString,
50023       std::string,
50024       TraceConfig_DataSource>;
50025 
50026   // Ceci n'est pas une pipe.
50027   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50028   // type (and users are expected to use it as such, hence kCamelCase name).
50029   // It is declared as a function to keep protozero bindings header-only as
50030   // inline constexpr variables are not available until C++17 (while inline
50031   // functions are).
50032   // TODO(altimin): Use inline variable instead after adopting C++17.
kProducerNameFilter()50033   static constexpr FieldMetadata_ProducerNameFilter kProducerNameFilter() { return {}; }
add_producer_name_filter(const char * data,size_t size)50034   void add_producer_name_filter(const char* data, size_t size) {
50035     AppendBytes(FieldMetadata_ProducerNameFilter::kFieldId, data, size);
50036   }
add_producer_name_filter(std::string value)50037   void add_producer_name_filter(std::string value) {
50038     static constexpr uint32_t field_id = FieldMetadata_ProducerNameFilter::kFieldId;
50039     // Call the appropriate protozero::Message::Append(field_id, ...)
50040     // method based on the type of the field.
50041     ::protozero::internal::FieldWriter<
50042       ::protozero::proto_utils::ProtoSchemaType::kString>
50043         ::Append(*this, field_id, value);
50044   }
50045 
50046   using FieldMetadata_ProducerNameRegexFilter =
50047     ::protozero::proto_utils::FieldMetadata<
50048       3,
50049       ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
50050       ::protozero::proto_utils::ProtoSchemaType::kString,
50051       std::string,
50052       TraceConfig_DataSource>;
50053 
50054   // Ceci n'est pas une pipe.
50055   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50056   // type (and users are expected to use it as such, hence kCamelCase name).
50057   // It is declared as a function to keep protozero bindings header-only as
50058   // inline constexpr variables are not available until C++17 (while inline
50059   // functions are).
50060   // TODO(altimin): Use inline variable instead after adopting C++17.
kProducerNameRegexFilter()50061   static constexpr FieldMetadata_ProducerNameRegexFilter kProducerNameRegexFilter() { return {}; }
add_producer_name_regex_filter(const char * data,size_t size)50062   void add_producer_name_regex_filter(const char* data, size_t size) {
50063     AppendBytes(FieldMetadata_ProducerNameRegexFilter::kFieldId, data, size);
50064   }
add_producer_name_regex_filter(std::string value)50065   void add_producer_name_regex_filter(std::string value) {
50066     static constexpr uint32_t field_id = FieldMetadata_ProducerNameRegexFilter::kFieldId;
50067     // Call the appropriate protozero::Message::Append(field_id, ...)
50068     // method based on the type of the field.
50069     ::protozero::internal::FieldWriter<
50070       ::protozero::proto_utils::ProtoSchemaType::kString>
50071         ::Append(*this, field_id, value);
50072   }
50073 };
50074 
50075 class TraceConfig_BufferConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
50076  public:
TraceConfig_BufferConfig_Decoder(const uint8_t * data,size_t len)50077   TraceConfig_BufferConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_BufferConfig_Decoder(const std::string & raw)50078   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)50079   explicit TraceConfig_BufferConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_size_kb() const50080   bool has_size_kb() const { return at<1>().valid(); }
size_kb() const50081   uint32_t size_kb() const { return at<1>().as_uint32(); }
has_fill_policy() const50082   bool has_fill_policy() const { return at<4>().valid(); }
fill_policy() const50083   int32_t fill_policy() const { return at<4>().as_int32(); }
50084 };
50085 
50086 class TraceConfig_BufferConfig : public ::protozero::Message {
50087  public:
50088   using Decoder = TraceConfig_BufferConfig_Decoder;
50089   enum : int32_t {
50090     kSizeKbFieldNumber = 1,
50091     kFillPolicyFieldNumber = 4,
50092   };
50093   using FillPolicy = ::perfetto::protos::pbzero::TraceConfig_BufferConfig_FillPolicy;
50094   static const FillPolicy UNSPECIFIED = TraceConfig_BufferConfig_FillPolicy_UNSPECIFIED;
50095   static const FillPolicy RING_BUFFER = TraceConfig_BufferConfig_FillPolicy_RING_BUFFER;
50096   static const FillPolicy DISCARD = TraceConfig_BufferConfig_FillPolicy_DISCARD;
50097 
50098   using FieldMetadata_SizeKb =
50099     ::protozero::proto_utils::FieldMetadata<
50100       1,
50101       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50102       ::protozero::proto_utils::ProtoSchemaType::kUint32,
50103       uint32_t,
50104       TraceConfig_BufferConfig>;
50105 
50106   // Ceci n'est pas une pipe.
50107   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50108   // type (and users are expected to use it as such, hence kCamelCase name).
50109   // It is declared as a function to keep protozero bindings header-only as
50110   // inline constexpr variables are not available until C++17 (while inline
50111   // functions are).
50112   // TODO(altimin): Use inline variable instead after adopting C++17.
kSizeKb()50113   static constexpr FieldMetadata_SizeKb kSizeKb() { return {}; }
set_size_kb(uint32_t value)50114   void set_size_kb(uint32_t value) {
50115     static constexpr uint32_t field_id = FieldMetadata_SizeKb::kFieldId;
50116     // Call the appropriate protozero::Message::Append(field_id, ...)
50117     // method based on the type of the field.
50118     ::protozero::internal::FieldWriter<
50119       ::protozero::proto_utils::ProtoSchemaType::kUint32>
50120         ::Append(*this, field_id, value);
50121   }
50122 
50123   using FieldMetadata_FillPolicy =
50124     ::protozero::proto_utils::FieldMetadata<
50125       4,
50126       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50127       ::protozero::proto_utils::ProtoSchemaType::kEnum,
50128       ::perfetto::protos::pbzero::TraceConfig_BufferConfig_FillPolicy,
50129       TraceConfig_BufferConfig>;
50130 
50131   // Ceci n'est pas une pipe.
50132   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50133   // type (and users are expected to use it as such, hence kCamelCase name).
50134   // It is declared as a function to keep protozero bindings header-only as
50135   // inline constexpr variables are not available until C++17 (while inline
50136   // functions are).
50137   // TODO(altimin): Use inline variable instead after adopting C++17.
kFillPolicy()50138   static constexpr FieldMetadata_FillPolicy kFillPolicy() { return {}; }
set_fill_policy(::perfetto::protos::pbzero::TraceConfig_BufferConfig_FillPolicy value)50139   void set_fill_policy(::perfetto::protos::pbzero::TraceConfig_BufferConfig_FillPolicy value) {
50140     static constexpr uint32_t field_id = FieldMetadata_FillPolicy::kFieldId;
50141     // Call the appropriate protozero::Message::Append(field_id, ...)
50142     // method based on the type of the field.
50143     ::protozero::internal::FieldWriter<
50144       ::protozero::proto_utils::ProtoSchemaType::kEnum>
50145         ::Append(*this, field_id, value);
50146   }
50147 };
50148 
50149 } // Namespace.
50150 } // Namespace.
50151 } // Namespace.
50152 #endif  // Include guard.
50153 // gen_amalgamated begin header: gen/protos/perfetto/trace/clock_snapshot.pbzero.h
50154 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
50155 
50156 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_CLOCK_SNAPSHOT_PROTO_H_
50157 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_CLOCK_SNAPSHOT_PROTO_H_
50158 
50159 #include <stddef.h>
50160 #include <stdint.h>
50161 
50162 // gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
50163 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
50164 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
50165 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
50166 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
50167 
50168 namespace perfetto {
50169 namespace protos {
50170 namespace pbzero {
50171 
50172 class ClockSnapshot_Clock;
50173 enum BuiltinClock : int32_t;
50174 
50175 enum ClockSnapshot_Clock_BuiltinClocks : int32_t {
50176   ClockSnapshot_Clock_BuiltinClocks_UNKNOWN = 0,
50177   ClockSnapshot_Clock_BuiltinClocks_REALTIME = 1,
50178   ClockSnapshot_Clock_BuiltinClocks_REALTIME_COARSE = 2,
50179   ClockSnapshot_Clock_BuiltinClocks_MONOTONIC = 3,
50180   ClockSnapshot_Clock_BuiltinClocks_MONOTONIC_COARSE = 4,
50181   ClockSnapshot_Clock_BuiltinClocks_MONOTONIC_RAW = 5,
50182   ClockSnapshot_Clock_BuiltinClocks_BOOTTIME = 6,
50183   ClockSnapshot_Clock_BuiltinClocks_BUILTIN_CLOCK_MAX_ID = 63,
50184 };
50185 
50186 const ClockSnapshot_Clock_BuiltinClocks ClockSnapshot_Clock_BuiltinClocks_MIN = ClockSnapshot_Clock_BuiltinClocks_UNKNOWN;
50187 const ClockSnapshot_Clock_BuiltinClocks ClockSnapshot_Clock_BuiltinClocks_MAX = ClockSnapshot_Clock_BuiltinClocks_BUILTIN_CLOCK_MAX_ID;
50188 
50189 class ClockSnapshot_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
50190  public:
ClockSnapshot_Decoder(const uint8_t * data,size_t len)50191   ClockSnapshot_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
ClockSnapshot_Decoder(const std::string & raw)50192   explicit ClockSnapshot_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
ClockSnapshot_Decoder(const::protozero::ConstBytes & raw)50193   explicit ClockSnapshot_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_clocks() const50194   bool has_clocks() const { return at<1>().valid(); }
clocks() const50195   ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> clocks() const { return GetRepeated<::protozero::ConstBytes>(1); }
has_primary_trace_clock() const50196   bool has_primary_trace_clock() const { return at<2>().valid(); }
primary_trace_clock() const50197   int32_t primary_trace_clock() const { return at<2>().as_int32(); }
50198 };
50199 
50200 class ClockSnapshot : public ::protozero::Message {
50201  public:
50202   using Decoder = ClockSnapshot_Decoder;
50203   enum : int32_t {
50204     kClocksFieldNumber = 1,
50205     kPrimaryTraceClockFieldNumber = 2,
50206   };
50207   using Clock = ::perfetto::protos::pbzero::ClockSnapshot_Clock;
50208 
50209   using FieldMetadata_Clocks =
50210     ::protozero::proto_utils::FieldMetadata<
50211       1,
50212       ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
50213       ::protozero::proto_utils::ProtoSchemaType::kMessage,
50214       ClockSnapshot_Clock,
50215       ClockSnapshot>;
50216 
50217   // Ceci n'est pas une pipe.
50218   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50219   // type (and users are expected to use it as such, hence kCamelCase name).
50220   // It is declared as a function to keep protozero bindings header-only as
50221   // inline constexpr variables are not available until C++17 (while inline
50222   // functions are).
50223   // TODO(altimin): Use inline variable instead after adopting C++17.
kClocks()50224   static constexpr FieldMetadata_Clocks kClocks() { return {}; }
add_clocks()50225   template <typename T = ClockSnapshot_Clock> T* add_clocks() {
50226     return BeginNestedMessage<T>(1);
50227   }
50228 
50229 
50230   using FieldMetadata_PrimaryTraceClock =
50231     ::protozero::proto_utils::FieldMetadata<
50232       2,
50233       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50234       ::protozero::proto_utils::ProtoSchemaType::kEnum,
50235       ::perfetto::protos::pbzero::BuiltinClock,
50236       ClockSnapshot>;
50237 
50238   // Ceci n'est pas une pipe.
50239   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50240   // type (and users are expected to use it as such, hence kCamelCase name).
50241   // It is declared as a function to keep protozero bindings header-only as
50242   // inline constexpr variables are not available until C++17 (while inline
50243   // functions are).
50244   // TODO(altimin): Use inline variable instead after adopting C++17.
kPrimaryTraceClock()50245   static constexpr FieldMetadata_PrimaryTraceClock kPrimaryTraceClock() { return {}; }
set_primary_trace_clock(::perfetto::protos::pbzero::BuiltinClock value)50246   void set_primary_trace_clock(::perfetto::protos::pbzero::BuiltinClock value) {
50247     static constexpr uint32_t field_id = FieldMetadata_PrimaryTraceClock::kFieldId;
50248     // Call the appropriate protozero::Message::Append(field_id, ...)
50249     // method based on the type of the field.
50250     ::protozero::internal::FieldWriter<
50251       ::protozero::proto_utils::ProtoSchemaType::kEnum>
50252         ::Append(*this, field_id, value);
50253   }
50254 };
50255 
50256 class ClockSnapshot_Clock_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
50257  public:
ClockSnapshot_Clock_Decoder(const uint8_t * data,size_t len)50258   ClockSnapshot_Clock_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
ClockSnapshot_Clock_Decoder(const std::string & raw)50259   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)50260   explicit ClockSnapshot_Clock_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_clock_id() const50261   bool has_clock_id() const { return at<1>().valid(); }
clock_id() const50262   uint32_t clock_id() const { return at<1>().as_uint32(); }
has_timestamp() const50263   bool has_timestamp() const { return at<2>().valid(); }
timestamp() const50264   uint64_t timestamp() const { return at<2>().as_uint64(); }
has_is_incremental() const50265   bool has_is_incremental() const { return at<3>().valid(); }
is_incremental() const50266   bool is_incremental() const { return at<3>().as_bool(); }
has_unit_multiplier_ns() const50267   bool has_unit_multiplier_ns() const { return at<4>().valid(); }
unit_multiplier_ns() const50268   uint64_t unit_multiplier_ns() const { return at<4>().as_uint64(); }
50269 };
50270 
50271 class ClockSnapshot_Clock : public ::protozero::Message {
50272  public:
50273   using Decoder = ClockSnapshot_Clock_Decoder;
50274   enum : int32_t {
50275     kClockIdFieldNumber = 1,
50276     kTimestampFieldNumber = 2,
50277     kIsIncrementalFieldNumber = 3,
50278     kUnitMultiplierNsFieldNumber = 4,
50279   };
50280   using BuiltinClocks = ::perfetto::protos::pbzero::ClockSnapshot_Clock_BuiltinClocks;
50281   static const BuiltinClocks UNKNOWN = ClockSnapshot_Clock_BuiltinClocks_UNKNOWN;
50282   static const BuiltinClocks REALTIME = ClockSnapshot_Clock_BuiltinClocks_REALTIME;
50283   static const BuiltinClocks REALTIME_COARSE = ClockSnapshot_Clock_BuiltinClocks_REALTIME_COARSE;
50284   static const BuiltinClocks MONOTONIC = ClockSnapshot_Clock_BuiltinClocks_MONOTONIC;
50285   static const BuiltinClocks MONOTONIC_COARSE = ClockSnapshot_Clock_BuiltinClocks_MONOTONIC_COARSE;
50286   static const BuiltinClocks MONOTONIC_RAW = ClockSnapshot_Clock_BuiltinClocks_MONOTONIC_RAW;
50287   static const BuiltinClocks BOOTTIME = ClockSnapshot_Clock_BuiltinClocks_BOOTTIME;
50288   static const BuiltinClocks BUILTIN_CLOCK_MAX_ID = ClockSnapshot_Clock_BuiltinClocks_BUILTIN_CLOCK_MAX_ID;
50289 
50290   using FieldMetadata_ClockId =
50291     ::protozero::proto_utils::FieldMetadata<
50292       1,
50293       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50294       ::protozero::proto_utils::ProtoSchemaType::kUint32,
50295       uint32_t,
50296       ClockSnapshot_Clock>;
50297 
50298   // Ceci n'est pas une pipe.
50299   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50300   // type (and users are expected to use it as such, hence kCamelCase name).
50301   // It is declared as a function to keep protozero bindings header-only as
50302   // inline constexpr variables are not available until C++17 (while inline
50303   // functions are).
50304   // TODO(altimin): Use inline variable instead after adopting C++17.
kClockId()50305   static constexpr FieldMetadata_ClockId kClockId() { return {}; }
set_clock_id(uint32_t value)50306   void set_clock_id(uint32_t value) {
50307     static constexpr uint32_t field_id = FieldMetadata_ClockId::kFieldId;
50308     // Call the appropriate protozero::Message::Append(field_id, ...)
50309     // method based on the type of the field.
50310     ::protozero::internal::FieldWriter<
50311       ::protozero::proto_utils::ProtoSchemaType::kUint32>
50312         ::Append(*this, field_id, value);
50313   }
50314 
50315   using FieldMetadata_Timestamp =
50316     ::protozero::proto_utils::FieldMetadata<
50317       2,
50318       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50319       ::protozero::proto_utils::ProtoSchemaType::kUint64,
50320       uint64_t,
50321       ClockSnapshot_Clock>;
50322 
50323   // Ceci n'est pas une pipe.
50324   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50325   // type (and users are expected to use it as such, hence kCamelCase name).
50326   // It is declared as a function to keep protozero bindings header-only as
50327   // inline constexpr variables are not available until C++17 (while inline
50328   // functions are).
50329   // TODO(altimin): Use inline variable instead after adopting C++17.
kTimestamp()50330   static constexpr FieldMetadata_Timestamp kTimestamp() { return {}; }
set_timestamp(uint64_t value)50331   void set_timestamp(uint64_t value) {
50332     static constexpr uint32_t field_id = FieldMetadata_Timestamp::kFieldId;
50333     // Call the appropriate protozero::Message::Append(field_id, ...)
50334     // method based on the type of the field.
50335     ::protozero::internal::FieldWriter<
50336       ::protozero::proto_utils::ProtoSchemaType::kUint64>
50337         ::Append(*this, field_id, value);
50338   }
50339 
50340   using FieldMetadata_IsIncremental =
50341     ::protozero::proto_utils::FieldMetadata<
50342       3,
50343       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50344       ::protozero::proto_utils::ProtoSchemaType::kBool,
50345       bool,
50346       ClockSnapshot_Clock>;
50347 
50348   // Ceci n'est pas une pipe.
50349   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50350   // type (and users are expected to use it as such, hence kCamelCase name).
50351   // It is declared as a function to keep protozero bindings header-only as
50352   // inline constexpr variables are not available until C++17 (while inline
50353   // functions are).
50354   // TODO(altimin): Use inline variable instead after adopting C++17.
kIsIncremental()50355   static constexpr FieldMetadata_IsIncremental kIsIncremental() { return {}; }
set_is_incremental(bool value)50356   void set_is_incremental(bool value) {
50357     static constexpr uint32_t field_id = FieldMetadata_IsIncremental::kFieldId;
50358     // Call the appropriate protozero::Message::Append(field_id, ...)
50359     // method based on the type of the field.
50360     ::protozero::internal::FieldWriter<
50361       ::protozero::proto_utils::ProtoSchemaType::kBool>
50362         ::Append(*this, field_id, value);
50363   }
50364 
50365   using FieldMetadata_UnitMultiplierNs =
50366     ::protozero::proto_utils::FieldMetadata<
50367       4,
50368       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50369       ::protozero::proto_utils::ProtoSchemaType::kUint64,
50370       uint64_t,
50371       ClockSnapshot_Clock>;
50372 
50373   // Ceci n'est pas une pipe.
50374   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50375   // type (and users are expected to use it as such, hence kCamelCase name).
50376   // It is declared as a function to keep protozero bindings header-only as
50377   // inline constexpr variables are not available until C++17 (while inline
50378   // functions are).
50379   // TODO(altimin): Use inline variable instead after adopting C++17.
kUnitMultiplierNs()50380   static constexpr FieldMetadata_UnitMultiplierNs kUnitMultiplierNs() { return {}; }
set_unit_multiplier_ns(uint64_t value)50381   void set_unit_multiplier_ns(uint64_t value) {
50382     static constexpr uint32_t field_id = FieldMetadata_UnitMultiplierNs::kFieldId;
50383     // Call the appropriate protozero::Message::Append(field_id, ...)
50384     // method based on the type of the field.
50385     ::protozero::internal::FieldWriter<
50386       ::protozero::proto_utils::ProtoSchemaType::kUint64>
50387         ::Append(*this, field_id, value);
50388   }
50389 };
50390 
50391 } // Namespace.
50392 } // Namespace.
50393 } // Namespace.
50394 #endif  // Include guard.
50395 // gen_amalgamated begin header: gen/protos/perfetto/trace/perfetto/tracing_service_event.pbzero.h
50396 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
50397 
50398 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PERFETTO_TRACING_SERVICE_EVENT_PROTO_H_
50399 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PERFETTO_TRACING_SERVICE_EVENT_PROTO_H_
50400 
50401 #include <stddef.h>
50402 #include <stdint.h>
50403 
50404 // gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
50405 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
50406 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
50407 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
50408 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
50409 
50410 namespace perfetto {
50411 namespace protos {
50412 namespace pbzero {
50413 
50414 
50415 class TracingServiceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
50416  public:
TracingServiceEvent_Decoder(const uint8_t * data,size_t len)50417   TracingServiceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TracingServiceEvent_Decoder(const std::string & raw)50418   explicit TracingServiceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
TracingServiceEvent_Decoder(const::protozero::ConstBytes & raw)50419   explicit TracingServiceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_tracing_started() const50420   bool has_tracing_started() const { return at<2>().valid(); }
tracing_started() const50421   bool tracing_started() const { return at<2>().as_bool(); }
has_all_data_sources_started() const50422   bool has_all_data_sources_started() const { return at<1>().valid(); }
all_data_sources_started() const50423   bool all_data_sources_started() const { return at<1>().as_bool(); }
has_all_data_sources_flushed() const50424   bool has_all_data_sources_flushed() const { return at<3>().valid(); }
all_data_sources_flushed() const50425   bool all_data_sources_flushed() const { return at<3>().as_bool(); }
has_read_tracing_buffers_completed() const50426   bool has_read_tracing_buffers_completed() const { return at<4>().valid(); }
read_tracing_buffers_completed() const50427   bool read_tracing_buffers_completed() const { return at<4>().as_bool(); }
has_tracing_disabled() const50428   bool has_tracing_disabled() const { return at<5>().valid(); }
tracing_disabled() const50429   bool tracing_disabled() const { return at<5>().as_bool(); }
has_seized_for_bugreport() const50430   bool has_seized_for_bugreport() const { return at<6>().valid(); }
seized_for_bugreport() const50431   bool seized_for_bugreport() const { return at<6>().as_bool(); }
50432 };
50433 
50434 class TracingServiceEvent : public ::protozero::Message {
50435  public:
50436   using Decoder = TracingServiceEvent_Decoder;
50437   enum : int32_t {
50438     kTracingStartedFieldNumber = 2,
50439     kAllDataSourcesStartedFieldNumber = 1,
50440     kAllDataSourcesFlushedFieldNumber = 3,
50441     kReadTracingBuffersCompletedFieldNumber = 4,
50442     kTracingDisabledFieldNumber = 5,
50443     kSeizedForBugreportFieldNumber = 6,
50444   };
50445 
50446   using FieldMetadata_TracingStarted =
50447     ::protozero::proto_utils::FieldMetadata<
50448       2,
50449       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50450       ::protozero::proto_utils::ProtoSchemaType::kBool,
50451       bool,
50452       TracingServiceEvent>;
50453 
50454   // Ceci n'est pas une pipe.
50455   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50456   // type (and users are expected to use it as such, hence kCamelCase name).
50457   // It is declared as a function to keep protozero bindings header-only as
50458   // inline constexpr variables are not available until C++17 (while inline
50459   // functions are).
50460   // TODO(altimin): Use inline variable instead after adopting C++17.
kTracingStarted()50461   static constexpr FieldMetadata_TracingStarted kTracingStarted() { return {}; }
set_tracing_started(bool value)50462   void set_tracing_started(bool value) {
50463     static constexpr uint32_t field_id = FieldMetadata_TracingStarted::kFieldId;
50464     // Call the appropriate protozero::Message::Append(field_id, ...)
50465     // method based on the type of the field.
50466     ::protozero::internal::FieldWriter<
50467       ::protozero::proto_utils::ProtoSchemaType::kBool>
50468         ::Append(*this, field_id, value);
50469   }
50470 
50471   using FieldMetadata_AllDataSourcesStarted =
50472     ::protozero::proto_utils::FieldMetadata<
50473       1,
50474       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50475       ::protozero::proto_utils::ProtoSchemaType::kBool,
50476       bool,
50477       TracingServiceEvent>;
50478 
50479   // Ceci n'est pas une pipe.
50480   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50481   // type (and users are expected to use it as such, hence kCamelCase name).
50482   // It is declared as a function to keep protozero bindings header-only as
50483   // inline constexpr variables are not available until C++17 (while inline
50484   // functions are).
50485   // TODO(altimin): Use inline variable instead after adopting C++17.
kAllDataSourcesStarted()50486   static constexpr FieldMetadata_AllDataSourcesStarted kAllDataSourcesStarted() { return {}; }
set_all_data_sources_started(bool value)50487   void set_all_data_sources_started(bool value) {
50488     static constexpr uint32_t field_id = FieldMetadata_AllDataSourcesStarted::kFieldId;
50489     // Call the appropriate protozero::Message::Append(field_id, ...)
50490     // method based on the type of the field.
50491     ::protozero::internal::FieldWriter<
50492       ::protozero::proto_utils::ProtoSchemaType::kBool>
50493         ::Append(*this, field_id, value);
50494   }
50495 
50496   using FieldMetadata_AllDataSourcesFlushed =
50497     ::protozero::proto_utils::FieldMetadata<
50498       3,
50499       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50500       ::protozero::proto_utils::ProtoSchemaType::kBool,
50501       bool,
50502       TracingServiceEvent>;
50503 
50504   // Ceci n'est pas une pipe.
50505   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50506   // type (and users are expected to use it as such, hence kCamelCase name).
50507   // It is declared as a function to keep protozero bindings header-only as
50508   // inline constexpr variables are not available until C++17 (while inline
50509   // functions are).
50510   // TODO(altimin): Use inline variable instead after adopting C++17.
kAllDataSourcesFlushed()50511   static constexpr FieldMetadata_AllDataSourcesFlushed kAllDataSourcesFlushed() { return {}; }
set_all_data_sources_flushed(bool value)50512   void set_all_data_sources_flushed(bool value) {
50513     static constexpr uint32_t field_id = FieldMetadata_AllDataSourcesFlushed::kFieldId;
50514     // Call the appropriate protozero::Message::Append(field_id, ...)
50515     // method based on the type of the field.
50516     ::protozero::internal::FieldWriter<
50517       ::protozero::proto_utils::ProtoSchemaType::kBool>
50518         ::Append(*this, field_id, value);
50519   }
50520 
50521   using FieldMetadata_ReadTracingBuffersCompleted =
50522     ::protozero::proto_utils::FieldMetadata<
50523       4,
50524       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50525       ::protozero::proto_utils::ProtoSchemaType::kBool,
50526       bool,
50527       TracingServiceEvent>;
50528 
50529   // Ceci n'est pas une pipe.
50530   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50531   // type (and users are expected to use it as such, hence kCamelCase name).
50532   // It is declared as a function to keep protozero bindings header-only as
50533   // inline constexpr variables are not available until C++17 (while inline
50534   // functions are).
50535   // TODO(altimin): Use inline variable instead after adopting C++17.
kReadTracingBuffersCompleted()50536   static constexpr FieldMetadata_ReadTracingBuffersCompleted kReadTracingBuffersCompleted() { return {}; }
set_read_tracing_buffers_completed(bool value)50537   void set_read_tracing_buffers_completed(bool value) {
50538     static constexpr uint32_t field_id = FieldMetadata_ReadTracingBuffersCompleted::kFieldId;
50539     // Call the appropriate protozero::Message::Append(field_id, ...)
50540     // method based on the type of the field.
50541     ::protozero::internal::FieldWriter<
50542       ::protozero::proto_utils::ProtoSchemaType::kBool>
50543         ::Append(*this, field_id, value);
50544   }
50545 
50546   using FieldMetadata_TracingDisabled =
50547     ::protozero::proto_utils::FieldMetadata<
50548       5,
50549       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50550       ::protozero::proto_utils::ProtoSchemaType::kBool,
50551       bool,
50552       TracingServiceEvent>;
50553 
50554   // Ceci n'est pas une pipe.
50555   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50556   // type (and users are expected to use it as such, hence kCamelCase name).
50557   // It is declared as a function to keep protozero bindings header-only as
50558   // inline constexpr variables are not available until C++17 (while inline
50559   // functions are).
50560   // TODO(altimin): Use inline variable instead after adopting C++17.
kTracingDisabled()50561   static constexpr FieldMetadata_TracingDisabled kTracingDisabled() { return {}; }
set_tracing_disabled(bool value)50562   void set_tracing_disabled(bool value) {
50563     static constexpr uint32_t field_id = FieldMetadata_TracingDisabled::kFieldId;
50564     // Call the appropriate protozero::Message::Append(field_id, ...)
50565     // method based on the type of the field.
50566     ::protozero::internal::FieldWriter<
50567       ::protozero::proto_utils::ProtoSchemaType::kBool>
50568         ::Append(*this, field_id, value);
50569   }
50570 
50571   using FieldMetadata_SeizedForBugreport =
50572     ::protozero::proto_utils::FieldMetadata<
50573       6,
50574       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50575       ::protozero::proto_utils::ProtoSchemaType::kBool,
50576       bool,
50577       TracingServiceEvent>;
50578 
50579   // Ceci n'est pas une pipe.
50580   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50581   // type (and users are expected to use it as such, hence kCamelCase name).
50582   // It is declared as a function to keep protozero bindings header-only as
50583   // inline constexpr variables are not available until C++17 (while inline
50584   // functions are).
50585   // TODO(altimin): Use inline variable instead after adopting C++17.
kSeizedForBugreport()50586   static constexpr FieldMetadata_SeizedForBugreport kSeizedForBugreport() { return {}; }
set_seized_for_bugreport(bool value)50587   void set_seized_for_bugreport(bool value) {
50588     static constexpr uint32_t field_id = FieldMetadata_SeizedForBugreport::kFieldId;
50589     // Call the appropriate protozero::Message::Append(field_id, ...)
50590     // method based on the type of the field.
50591     ::protozero::internal::FieldWriter<
50592       ::protozero::proto_utils::ProtoSchemaType::kBool>
50593         ::Append(*this, field_id, value);
50594   }
50595 };
50596 
50597 } // Namespace.
50598 } // Namespace.
50599 } // Namespace.
50600 #endif  // Include guard.
50601 // gen_amalgamated begin header: gen/protos/perfetto/trace/system_info.pbzero.h
50602 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
50603 
50604 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_SYSTEM_INFO_PROTO_H_
50605 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_SYSTEM_INFO_PROTO_H_
50606 
50607 #include <stddef.h>
50608 #include <stdint.h>
50609 
50610 // gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
50611 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
50612 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
50613 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
50614 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
50615 
50616 namespace perfetto {
50617 namespace protos {
50618 namespace pbzero {
50619 
50620 class Utsname;
50621 
50622 class SystemInfo_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
50623  public:
SystemInfo_Decoder(const uint8_t * data,size_t len)50624   SystemInfo_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
SystemInfo_Decoder(const std::string & raw)50625   explicit SystemInfo_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
SystemInfo_Decoder(const::protozero::ConstBytes & raw)50626   explicit SystemInfo_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_utsname() const50627   bool has_utsname() const { return at<1>().valid(); }
utsname() const50628   ::protozero::ConstBytes utsname() const { return at<1>().as_bytes(); }
has_android_build_fingerprint() const50629   bool has_android_build_fingerprint() const { return at<2>().valid(); }
android_build_fingerprint() const50630   ::protozero::ConstChars android_build_fingerprint() const { return at<2>().as_string(); }
has_hz() const50631   bool has_hz() const { return at<3>().valid(); }
hz() const50632   int64_t hz() const { return at<3>().as_int64(); }
has_tracing_service_version() const50633   bool has_tracing_service_version() const { return at<4>().valid(); }
tracing_service_version() const50634   ::protozero::ConstChars tracing_service_version() const { return at<4>().as_string(); }
50635 };
50636 
50637 class SystemInfo : public ::protozero::Message {
50638  public:
50639   using Decoder = SystemInfo_Decoder;
50640   enum : int32_t {
50641     kUtsnameFieldNumber = 1,
50642     kAndroidBuildFingerprintFieldNumber = 2,
50643     kHzFieldNumber = 3,
50644     kTracingServiceVersionFieldNumber = 4,
50645   };
50646 
50647   using FieldMetadata_Utsname =
50648     ::protozero::proto_utils::FieldMetadata<
50649       1,
50650       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50651       ::protozero::proto_utils::ProtoSchemaType::kMessage,
50652       Utsname,
50653       SystemInfo>;
50654 
50655   // Ceci n'est pas une pipe.
50656   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50657   // type (and users are expected to use it as such, hence kCamelCase name).
50658   // It is declared as a function to keep protozero bindings header-only as
50659   // inline constexpr variables are not available until C++17 (while inline
50660   // functions are).
50661   // TODO(altimin): Use inline variable instead after adopting C++17.
kUtsname()50662   static constexpr FieldMetadata_Utsname kUtsname() { return {}; }
set_utsname()50663   template <typename T = Utsname> T* set_utsname() {
50664     return BeginNestedMessage<T>(1);
50665   }
50666 
50667 
50668   using FieldMetadata_AndroidBuildFingerprint =
50669     ::protozero::proto_utils::FieldMetadata<
50670       2,
50671       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50672       ::protozero::proto_utils::ProtoSchemaType::kString,
50673       std::string,
50674       SystemInfo>;
50675 
50676   // Ceci n'est pas une pipe.
50677   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50678   // type (and users are expected to use it as such, hence kCamelCase name).
50679   // It is declared as a function to keep protozero bindings header-only as
50680   // inline constexpr variables are not available until C++17 (while inline
50681   // functions are).
50682   // TODO(altimin): Use inline variable instead after adopting C++17.
kAndroidBuildFingerprint()50683   static constexpr FieldMetadata_AndroidBuildFingerprint kAndroidBuildFingerprint() { return {}; }
set_android_build_fingerprint(const char * data,size_t size)50684   void set_android_build_fingerprint(const char* data, size_t size) {
50685     AppendBytes(FieldMetadata_AndroidBuildFingerprint::kFieldId, data, size);
50686   }
set_android_build_fingerprint(std::string value)50687   void set_android_build_fingerprint(std::string value) {
50688     static constexpr uint32_t field_id = FieldMetadata_AndroidBuildFingerprint::kFieldId;
50689     // Call the appropriate protozero::Message::Append(field_id, ...)
50690     // method based on the type of the field.
50691     ::protozero::internal::FieldWriter<
50692       ::protozero::proto_utils::ProtoSchemaType::kString>
50693         ::Append(*this, field_id, value);
50694   }
50695 
50696   using FieldMetadata_Hz =
50697     ::protozero::proto_utils::FieldMetadata<
50698       3,
50699       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50700       ::protozero::proto_utils::ProtoSchemaType::kInt64,
50701       int64_t,
50702       SystemInfo>;
50703 
50704   // Ceci n'est pas une pipe.
50705   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50706   // type (and users are expected to use it as such, hence kCamelCase name).
50707   // It is declared as a function to keep protozero bindings header-only as
50708   // inline constexpr variables are not available until C++17 (while inline
50709   // functions are).
50710   // TODO(altimin): Use inline variable instead after adopting C++17.
kHz()50711   static constexpr FieldMetadata_Hz kHz() { return {}; }
set_hz(int64_t value)50712   void set_hz(int64_t value) {
50713     static constexpr uint32_t field_id = FieldMetadata_Hz::kFieldId;
50714     // Call the appropriate protozero::Message::Append(field_id, ...)
50715     // method based on the type of the field.
50716     ::protozero::internal::FieldWriter<
50717       ::protozero::proto_utils::ProtoSchemaType::kInt64>
50718         ::Append(*this, field_id, value);
50719   }
50720 
50721   using FieldMetadata_TracingServiceVersion =
50722     ::protozero::proto_utils::FieldMetadata<
50723       4,
50724       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50725       ::protozero::proto_utils::ProtoSchemaType::kString,
50726       std::string,
50727       SystemInfo>;
50728 
50729   // Ceci n'est pas une pipe.
50730   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50731   // type (and users are expected to use it as such, hence kCamelCase name).
50732   // It is declared as a function to keep protozero bindings header-only as
50733   // inline constexpr variables are not available until C++17 (while inline
50734   // functions are).
50735   // TODO(altimin): Use inline variable instead after adopting C++17.
kTracingServiceVersion()50736   static constexpr FieldMetadata_TracingServiceVersion kTracingServiceVersion() { return {}; }
set_tracing_service_version(const char * data,size_t size)50737   void set_tracing_service_version(const char* data, size_t size) {
50738     AppendBytes(FieldMetadata_TracingServiceVersion::kFieldId, data, size);
50739   }
set_tracing_service_version(std::string value)50740   void set_tracing_service_version(std::string value) {
50741     static constexpr uint32_t field_id = FieldMetadata_TracingServiceVersion::kFieldId;
50742     // Call the appropriate protozero::Message::Append(field_id, ...)
50743     // method based on the type of the field.
50744     ::protozero::internal::FieldWriter<
50745       ::protozero::proto_utils::ProtoSchemaType::kString>
50746         ::Append(*this, field_id, value);
50747   }
50748 };
50749 
50750 class Utsname_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
50751  public:
Utsname_Decoder(const uint8_t * data,size_t len)50752   Utsname_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
Utsname_Decoder(const std::string & raw)50753   explicit Utsname_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
Utsname_Decoder(const::protozero::ConstBytes & raw)50754   explicit Utsname_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_sysname() const50755   bool has_sysname() const { return at<1>().valid(); }
sysname() const50756   ::protozero::ConstChars sysname() const { return at<1>().as_string(); }
has_version() const50757   bool has_version() const { return at<2>().valid(); }
version() const50758   ::protozero::ConstChars version() const { return at<2>().as_string(); }
has_release() const50759   bool has_release() const { return at<3>().valid(); }
release() const50760   ::protozero::ConstChars release() const { return at<3>().as_string(); }
has_machine() const50761   bool has_machine() const { return at<4>().valid(); }
machine() const50762   ::protozero::ConstChars machine() const { return at<4>().as_string(); }
50763 };
50764 
50765 class Utsname : public ::protozero::Message {
50766  public:
50767   using Decoder = Utsname_Decoder;
50768   enum : int32_t {
50769     kSysnameFieldNumber = 1,
50770     kVersionFieldNumber = 2,
50771     kReleaseFieldNumber = 3,
50772     kMachineFieldNumber = 4,
50773   };
50774 
50775   using FieldMetadata_Sysname =
50776     ::protozero::proto_utils::FieldMetadata<
50777       1,
50778       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50779       ::protozero::proto_utils::ProtoSchemaType::kString,
50780       std::string,
50781       Utsname>;
50782 
50783   // Ceci n'est pas une pipe.
50784   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50785   // type (and users are expected to use it as such, hence kCamelCase name).
50786   // It is declared as a function to keep protozero bindings header-only as
50787   // inline constexpr variables are not available until C++17 (while inline
50788   // functions are).
50789   // TODO(altimin): Use inline variable instead after adopting C++17.
kSysname()50790   static constexpr FieldMetadata_Sysname kSysname() { return {}; }
set_sysname(const char * data,size_t size)50791   void set_sysname(const char* data, size_t size) {
50792     AppendBytes(FieldMetadata_Sysname::kFieldId, data, size);
50793   }
set_sysname(std::string value)50794   void set_sysname(std::string value) {
50795     static constexpr uint32_t field_id = FieldMetadata_Sysname::kFieldId;
50796     // Call the appropriate protozero::Message::Append(field_id, ...)
50797     // method based on the type of the field.
50798     ::protozero::internal::FieldWriter<
50799       ::protozero::proto_utils::ProtoSchemaType::kString>
50800         ::Append(*this, field_id, value);
50801   }
50802 
50803   using FieldMetadata_Version =
50804     ::protozero::proto_utils::FieldMetadata<
50805       2,
50806       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50807       ::protozero::proto_utils::ProtoSchemaType::kString,
50808       std::string,
50809       Utsname>;
50810 
50811   // Ceci n'est pas une pipe.
50812   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50813   // type (and users are expected to use it as such, hence kCamelCase name).
50814   // It is declared as a function to keep protozero bindings header-only as
50815   // inline constexpr variables are not available until C++17 (while inline
50816   // functions are).
50817   // TODO(altimin): Use inline variable instead after adopting C++17.
kVersion()50818   static constexpr FieldMetadata_Version kVersion() { return {}; }
set_version(const char * data,size_t size)50819   void set_version(const char* data, size_t size) {
50820     AppendBytes(FieldMetadata_Version::kFieldId, data, size);
50821   }
set_version(std::string value)50822   void set_version(std::string value) {
50823     static constexpr uint32_t field_id = FieldMetadata_Version::kFieldId;
50824     // Call the appropriate protozero::Message::Append(field_id, ...)
50825     // method based on the type of the field.
50826     ::protozero::internal::FieldWriter<
50827       ::protozero::proto_utils::ProtoSchemaType::kString>
50828         ::Append(*this, field_id, value);
50829   }
50830 
50831   using FieldMetadata_Release =
50832     ::protozero::proto_utils::FieldMetadata<
50833       3,
50834       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50835       ::protozero::proto_utils::ProtoSchemaType::kString,
50836       std::string,
50837       Utsname>;
50838 
50839   // Ceci n'est pas une pipe.
50840   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50841   // type (and users are expected to use it as such, hence kCamelCase name).
50842   // It is declared as a function to keep protozero bindings header-only as
50843   // inline constexpr variables are not available until C++17 (while inline
50844   // functions are).
50845   // TODO(altimin): Use inline variable instead after adopting C++17.
kRelease()50846   static constexpr FieldMetadata_Release kRelease() { return {}; }
set_release(const char * data,size_t size)50847   void set_release(const char* data, size_t size) {
50848     AppendBytes(FieldMetadata_Release::kFieldId, data, size);
50849   }
set_release(std::string value)50850   void set_release(std::string value) {
50851     static constexpr uint32_t field_id = FieldMetadata_Release::kFieldId;
50852     // Call the appropriate protozero::Message::Append(field_id, ...)
50853     // method based on the type of the field.
50854     ::protozero::internal::FieldWriter<
50855       ::protozero::proto_utils::ProtoSchemaType::kString>
50856         ::Append(*this, field_id, value);
50857   }
50858 
50859   using FieldMetadata_Machine =
50860     ::protozero::proto_utils::FieldMetadata<
50861       4,
50862       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50863       ::protozero::proto_utils::ProtoSchemaType::kString,
50864       std::string,
50865       Utsname>;
50866 
50867   // Ceci n'est pas une pipe.
50868   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50869   // type (and users are expected to use it as such, hence kCamelCase name).
50870   // It is declared as a function to keep protozero bindings header-only as
50871   // inline constexpr variables are not available until C++17 (while inline
50872   // functions are).
50873   // TODO(altimin): Use inline variable instead after adopting C++17.
kMachine()50874   static constexpr FieldMetadata_Machine kMachine() { return {}; }
set_machine(const char * data,size_t size)50875   void set_machine(const char* data, size_t size) {
50876     AppendBytes(FieldMetadata_Machine::kFieldId, data, size);
50877   }
set_machine(std::string value)50878   void set_machine(std::string value) {
50879     static constexpr uint32_t field_id = FieldMetadata_Machine::kFieldId;
50880     // Call the appropriate protozero::Message::Append(field_id, ...)
50881     // method based on the type of the field.
50882     ::protozero::internal::FieldWriter<
50883       ::protozero::proto_utils::ProtoSchemaType::kString>
50884         ::Append(*this, field_id, value);
50885   }
50886 };
50887 
50888 } // Namespace.
50889 } // Namespace.
50890 } // Namespace.
50891 #endif  // Include guard.
50892 // gen_amalgamated begin header: gen/protos/perfetto/trace/trigger.pbzero.h
50893 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
50894 
50895 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRIGGER_PROTO_H_
50896 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRIGGER_PROTO_H_
50897 
50898 #include <stddef.h>
50899 #include <stdint.h>
50900 
50901 // gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
50902 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
50903 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
50904 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
50905 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
50906 
50907 namespace perfetto {
50908 namespace protos {
50909 namespace pbzero {
50910 
50911 
50912 class Trigger_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
50913  public:
Trigger_Decoder(const uint8_t * data,size_t len)50914   Trigger_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
Trigger_Decoder(const std::string & raw)50915   explicit Trigger_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
Trigger_Decoder(const::protozero::ConstBytes & raw)50916   explicit Trigger_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_trigger_name() const50917   bool has_trigger_name() const { return at<1>().valid(); }
trigger_name() const50918   ::protozero::ConstChars trigger_name() const { return at<1>().as_string(); }
has_producer_name() const50919   bool has_producer_name() const { return at<2>().valid(); }
producer_name() const50920   ::protozero::ConstChars producer_name() const { return at<2>().as_string(); }
has_trusted_producer_uid() const50921   bool has_trusted_producer_uid() const { return at<3>().valid(); }
trusted_producer_uid() const50922   int32_t trusted_producer_uid() const { return at<3>().as_int32(); }
50923 };
50924 
50925 class Trigger : public ::protozero::Message {
50926  public:
50927   using Decoder = Trigger_Decoder;
50928   enum : int32_t {
50929     kTriggerNameFieldNumber = 1,
50930     kProducerNameFieldNumber = 2,
50931     kTrustedProducerUidFieldNumber = 3,
50932   };
50933 
50934   using FieldMetadata_TriggerName =
50935     ::protozero::proto_utils::FieldMetadata<
50936       1,
50937       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50938       ::protozero::proto_utils::ProtoSchemaType::kString,
50939       std::string,
50940       Trigger>;
50941 
50942   // Ceci n'est pas une pipe.
50943   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50944   // type (and users are expected to use it as such, hence kCamelCase name).
50945   // It is declared as a function to keep protozero bindings header-only as
50946   // inline constexpr variables are not available until C++17 (while inline
50947   // functions are).
50948   // TODO(altimin): Use inline variable instead after adopting C++17.
kTriggerName()50949   static constexpr FieldMetadata_TriggerName kTriggerName() { return {}; }
set_trigger_name(const char * data,size_t size)50950   void set_trigger_name(const char* data, size_t size) {
50951     AppendBytes(FieldMetadata_TriggerName::kFieldId, data, size);
50952   }
set_trigger_name(std::string value)50953   void set_trigger_name(std::string value) {
50954     static constexpr uint32_t field_id = FieldMetadata_TriggerName::kFieldId;
50955     // Call the appropriate protozero::Message::Append(field_id, ...)
50956     // method based on the type of the field.
50957     ::protozero::internal::FieldWriter<
50958       ::protozero::proto_utils::ProtoSchemaType::kString>
50959         ::Append(*this, field_id, value);
50960   }
50961 
50962   using FieldMetadata_ProducerName =
50963     ::protozero::proto_utils::FieldMetadata<
50964       2,
50965       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50966       ::protozero::proto_utils::ProtoSchemaType::kString,
50967       std::string,
50968       Trigger>;
50969 
50970   // Ceci n'est pas une pipe.
50971   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50972   // type (and users are expected to use it as such, hence kCamelCase name).
50973   // It is declared as a function to keep protozero bindings header-only as
50974   // inline constexpr variables are not available until C++17 (while inline
50975   // functions are).
50976   // TODO(altimin): Use inline variable instead after adopting C++17.
kProducerName()50977   static constexpr FieldMetadata_ProducerName kProducerName() { return {}; }
set_producer_name(const char * data,size_t size)50978   void set_producer_name(const char* data, size_t size) {
50979     AppendBytes(FieldMetadata_ProducerName::kFieldId, data, size);
50980   }
set_producer_name(std::string value)50981   void set_producer_name(std::string value) {
50982     static constexpr uint32_t field_id = FieldMetadata_ProducerName::kFieldId;
50983     // Call the appropriate protozero::Message::Append(field_id, ...)
50984     // method based on the type of the field.
50985     ::protozero::internal::FieldWriter<
50986       ::protozero::proto_utils::ProtoSchemaType::kString>
50987         ::Append(*this, field_id, value);
50988   }
50989 
50990   using FieldMetadata_TrustedProducerUid =
50991     ::protozero::proto_utils::FieldMetadata<
50992       3,
50993       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50994       ::protozero::proto_utils::ProtoSchemaType::kInt32,
50995       int32_t,
50996       Trigger>;
50997 
50998   // Ceci n'est pas une pipe.
50999   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
51000   // type (and users are expected to use it as such, hence kCamelCase name).
51001   // It is declared as a function to keep protozero bindings header-only as
51002   // inline constexpr variables are not available until C++17 (while inline
51003   // functions are).
51004   // TODO(altimin): Use inline variable instead after adopting C++17.
kTrustedProducerUid()51005   static constexpr FieldMetadata_TrustedProducerUid kTrustedProducerUid() { return {}; }
set_trusted_producer_uid(int32_t value)51006   void set_trusted_producer_uid(int32_t value) {
51007     static constexpr uint32_t field_id = FieldMetadata_TrustedProducerUid::kFieldId;
51008     // Call the appropriate protozero::Message::Append(field_id, ...)
51009     // method based on the type of the field.
51010     ::protozero::internal::FieldWriter<
51011       ::protozero::proto_utils::ProtoSchemaType::kInt32>
51012         ::Append(*this, field_id, value);
51013   }
51014 };
51015 
51016 } // Namespace.
51017 } // Namespace.
51018 } // Namespace.
51019 #endif  // Include guard.
51020 /*
51021  * Copyright (C) 2017 The Android Open Source Project
51022  *
51023  * Licensed under the Apache License, Version 2.0 (the "License");
51024  * you may not use this file except in compliance with the License.
51025  * You may obtain a copy of the License at
51026  *
51027  *      http://www.apache.org/licenses/LICENSE-2.0
51028  *
51029  * Unless required by applicable law or agreed to in writing, software
51030  * distributed under the License is distributed on an "AS IS" BASIS,
51031  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
51032  * See the License for the specific language governing permissions and
51033  * limitations under the License.
51034  */
51035 
51036 // gen_amalgamated expanded: #include "src/tracing/core/tracing_service_impl.h"
51037 
51038 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
51039 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
51040 
51041 #include <errno.h>
51042 #include <inttypes.h>
51043 #include <limits.h>
51044 #include <string.h>
51045 #include <regex>
51046 #include <unordered_set>
51047 
51048 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
51049     !PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
51050 #include <sys/uio.h>
51051 #include <sys/utsname.h>
51052 #include <unistd.h>
51053 #endif
51054 
51055 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
51056 #include <sys/system_properties.h>
51057 #if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
51058 // gen_amalgamated expanded: #include "src/android_internal/lazy_library_loader.h"    // nogncheck
51059 // gen_amalgamated expanded: #include "src/android_internal/tracing_service_proxy.h"  // nogncheck
51060 #endif  // PERFETTO_ANDROID_BUILD
51061 #endif  // PERFETTO_OS_ANDROID
51062 
51063 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
51064     PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
51065     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
51066 #define PERFETTO_HAS_CHMOD
51067 #include <sys/stat.h>
51068 #endif
51069 
51070 #include <algorithm>
51071 
51072 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
51073 // gen_amalgamated expanded: #include "perfetto/base/status.h"
51074 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
51075 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
51076 // gen_amalgamated expanded: #include "perfetto/ext/base/metatrace.h"
51077 // gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
51078 // gen_amalgamated expanded: #include "perfetto/ext/base/temp_file.h"
51079 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
51080 // gen_amalgamated expanded: #include "perfetto/ext/base/version.h"
51081 // gen_amalgamated expanded: #include "perfetto/ext/base/watchdog.h"
51082 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
51083 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
51084 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/observable_events.h"
51085 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
51086 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
51087 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
51088 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
51089 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
51090 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
51091 // gen_amalgamated expanded: #include "perfetto/protozero/static_buffer.h"
51092 // gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
51093 // gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_capabilities.h"
51094 // gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_state.h"
51095 // gen_amalgamated expanded: #include "src/android_stats/statsd_logging_helper.h"
51096 // gen_amalgamated expanded: #include "src/protozero/filtering/message_filter.h"
51097 // gen_amalgamated expanded: #include "src/tracing/core/packet_stream_validator.h"
51098 // gen_amalgamated expanded: #include "src/tracing/core/shared_memory_arbiter_impl.h"
51099 // gen_amalgamated expanded: #include "src/tracing/core/trace_buffer.h"
51100 
51101 // gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"
51102 // gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.pbzero.h"
51103 // gen_amalgamated expanded: #include "protos/perfetto/common/trace_stats.pbzero.h"
51104 // gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.pbzero.h"
51105 // gen_amalgamated expanded: #include "protos/perfetto/trace/clock_snapshot.pbzero.h"
51106 // gen_amalgamated expanded: #include "protos/perfetto/trace/perfetto/tracing_service_event.pbzero.h"
51107 // gen_amalgamated expanded: #include "protos/perfetto/trace/system_info.pbzero.h"
51108 // gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
51109 // gen_amalgamated expanded: #include "protos/perfetto/trace/trigger.pbzero.h"
51110 
51111 // General note: this class must assume that Producers are malicious and will
51112 // try to crash / exploit this class. We can trust pointers because they come
51113 // from the IPC layer, but we should never assume that that the producer calls
51114 // come in the right order or their arguments are sane / within bounds.
51115 
51116 // This is a macro because we want the call-site line number for the ELOG.
51117 #define PERFETTO_SVC_ERR(...) \
51118   (PERFETTO_ELOG(__VA_ARGS__), ::perfetto::base::ErrStatus(__VA_ARGS__))
51119 
51120 namespace perfetto {
51121 
51122 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
51123     PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
51124 // These are the only SELinux approved dir for trace files that are created
51125 // directly by traced.
51126 const char* kTraceDirBasePath = "/data/misc/perfetto-traces/";
51127 const char* kAndroidProductionBugreportTracePath =
51128     "/data/misc/perfetto-traces/bugreport/systrace.pftrace";
51129 #endif
51130 
51131 namespace {
51132 constexpr int kMaxBuffersPerConsumer = 128;
51133 constexpr uint32_t kDefaultSnapshotsIntervalMs = 10 * 1000;
51134 constexpr int kDefaultWriteIntoFilePeriodMs = 5000;
51135 constexpr int kMaxConcurrentTracingSessions = 15;
51136 constexpr int kMaxConcurrentTracingSessionsPerUid = 5;
51137 constexpr int kMaxConcurrentTracingSessionsForStatsdUid = 10;
51138 constexpr int64_t kMinSecondsBetweenTracesGuardrail = 5 * 60;
51139 
51140 constexpr uint32_t kMillisPerHour = 3600000;
51141 constexpr uint32_t kMillisPerDay = kMillisPerHour * 24;
51142 constexpr uint32_t kMaxTracingDurationMillis = 7 * 24 * kMillisPerHour;
51143 
51144 // These apply only if enable_extra_guardrails is true.
51145 constexpr uint32_t kGuardrailsMaxTracingBufferSizeKb = 128 * 1024;
51146 constexpr uint32_t kGuardrailsMaxTracingDurationMillis = 24 * kMillisPerHour;
51147 
51148 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) || PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
51149 struct iovec {
51150   void* iov_base;  // Address
51151   size_t iov_len;  // Block size
51152 };
51153 
51154 // Simple implementation of writev. Note that this does not give the atomicity
51155 // guarantees of a real writev, but we don't depend on these (we aren't writing
51156 // to the same file from another thread).
writev(int fd,const struct iovec * iov,int iovcnt)51157 ssize_t writev(int fd, const struct iovec* iov, int iovcnt) {
51158   ssize_t total_size = 0;
51159   for (int i = 0; i < iovcnt; ++i) {
51160     ssize_t current_size = base::WriteAll(fd, iov[i].iov_base, iov[i].iov_len);
51161     if (current_size != static_cast<ssize_t>(iov[i].iov_len))
51162       return -1;
51163     total_size += current_size;
51164   }
51165   return total_size;
51166 }
51167 
51168 #define IOV_MAX 1024  // Linux compatible limit.
51169 
51170 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) ||
51171         // PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
51172 
51173 // Partially encodes a CommitDataRequest in an int32 for the purposes of
51174 // metatracing. Note that it encodes only the bottom 10 bits of the producer id
51175 // (which is technically 16 bits wide).
51176 //
51177 // Format (by bit range):
51178 // [   31 ][         30 ][             29:20 ][            19:10 ][        9:0]
51179 // [unused][has flush id][num chunks to patch][num chunks to move][producer id]
EncodeCommitDataRequest(ProducerID producer_id,const CommitDataRequest & req_untrusted)51180 static int32_t EncodeCommitDataRequest(ProducerID producer_id,
51181                                        const CommitDataRequest& req_untrusted) {
51182   uint32_t cmov = static_cast<uint32_t>(req_untrusted.chunks_to_move_size());
51183   uint32_t cpatch = static_cast<uint32_t>(req_untrusted.chunks_to_patch_size());
51184   uint32_t has_flush_id = req_untrusted.flush_request_id() != 0;
51185 
51186   uint32_t mask = (1 << 10) - 1;
51187   uint32_t acc = 0;
51188   acc |= has_flush_id << 30;
51189   acc |= (cpatch & mask) << 20;
51190   acc |= (cmov & mask) << 10;
51191   acc |= (producer_id & mask);
51192   return static_cast<int32_t>(acc);
51193 }
51194 
SerializeAndAppendPacket(std::vector<TracePacket> * packets,std::vector<uint8_t> packet)51195 void SerializeAndAppendPacket(std::vector<TracePacket>* packets,
51196                               std::vector<uint8_t> packet) {
51197   Slice slice = Slice::Allocate(packet.size());
51198   memcpy(slice.own_data(), packet.data(), packet.size());
51199   packets->emplace_back();
51200   packets->back().AddSlice(std::move(slice));
51201 }
51202 
EnsureValidShmSizes(size_t shm_size,size_t page_size)51203 std::tuple<size_t /*shm_size*/, size_t /*page_size*/> EnsureValidShmSizes(
51204     size_t shm_size,
51205     size_t page_size) {
51206   // Theoretically the max page size supported by the ABI is 64KB.
51207   // However, the current implementation of TraceBuffer (the non-shared
51208   // userspace buffer where the service copies data) supports at most
51209   // 32K. Setting 64K "works" from the producer<>consumer viewpoint
51210   // but then causes the data to be discarded when copying it into
51211   // TraceBuffer.
51212   constexpr size_t kMaxPageSize = 32 * 1024;
51213   static_assert(kMaxPageSize <= SharedMemoryABI::kMaxPageSize, "");
51214 
51215   if (page_size == 0)
51216     page_size = TracingServiceImpl::kDefaultShmPageSize;
51217   if (shm_size == 0)
51218     shm_size = TracingServiceImpl::kDefaultShmSize;
51219 
51220   page_size = std::min<size_t>(page_size, kMaxPageSize);
51221   shm_size = std::min<size_t>(shm_size, TracingServiceImpl::kMaxShmSize);
51222 
51223   // The tracing page size has to be multiple of 4K. On some systems (e.g. Mac
51224   // on Arm64) the system page size can be larger (e.g., 16K). That doesn't
51225   // matter here, because the tracing page size is just a logical partitioning
51226   // and does not have any dependencies on kernel mm syscalls (read: it's fine
51227   // to have trace page sizes of 4K on a system where the kernel page size is
51228   // 16K).
51229   bool page_size_is_valid = page_size >= SharedMemoryABI::kMinPageSize;
51230   page_size_is_valid &= page_size % SharedMemoryABI::kMinPageSize == 0;
51231 
51232   // Only allow power of two numbers of pages, i.e. 1, 2, 4, 8 pages.
51233   size_t num_pages = page_size / SharedMemoryABI::kMinPageSize;
51234   page_size_is_valid &= (num_pages & (num_pages - 1)) == 0;
51235 
51236   if (!page_size_is_valid || shm_size < page_size ||
51237       shm_size % page_size != 0) {
51238     return std::make_tuple(TracingServiceImpl::kDefaultShmSize,
51239                            TracingServiceImpl::kDefaultShmPageSize);
51240   }
51241   return std::make_tuple(shm_size, page_size);
51242 }
51243 
NameMatchesFilter(const std::string & name,const std::vector<std::string> & name_filter,const std::vector<std::string> & name_regex_filter)51244 bool NameMatchesFilter(const std::string& name,
51245                        const std::vector<std::string>& name_filter,
51246                        const std::vector<std::string>& name_regex_filter) {
51247   bool filter_is_set = !name_filter.empty() || !name_regex_filter.empty();
51248   if (!filter_is_set)
51249     return true;
51250   bool filter_matches = std::find(name_filter.begin(), name_filter.end(),
51251                                   name) != name_filter.end();
51252   bool filter_regex_matches =
51253       std::find_if(name_regex_filter.begin(), name_regex_filter.end(),
51254                    [&](const std::string& regex) {
51255                      return std::regex_match(
51256                          name, std::regex(regex, std::regex::extended));
51257                    }) != name_regex_filter.end();
51258   return filter_matches || filter_regex_matches;
51259 }
51260 
51261 // Used when:
51262 // 1. TraceConfig.write_into_file == true and output_path is not empty.
51263 // 2. Calling SaveTraceForBugreport(), from perfetto --save-for-bugreport.
CreateTraceFile(const std::string & path,bool overwrite)51264 base::ScopedFile CreateTraceFile(const std::string& path, bool overwrite) {
51265 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
51266     PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
51267   // This is NOT trying to preserve any security property, SELinux does that.
51268   // It just improves the actionability of the error when people try to save the
51269   // trace in a location that is not SELinux-allowed (a generic "permission
51270   // denied" vs "don't put it here, put it there").
51271   if (!base::StartsWith(path, kTraceDirBasePath)) {
51272     PERFETTO_ELOG("Invalid output_path %s. On Android it must be within %s.",
51273                   path.c_str(), kTraceDirBasePath);
51274     return base::ScopedFile();
51275   }
51276 #endif
51277   // O_CREAT | O_EXCL will fail if the file exists already.
51278   const int flags = O_RDWR | O_CREAT | (overwrite ? O_TRUNC : O_EXCL);
51279   auto fd = base::OpenFile(path, flags, 0600);
51280   if (fd) {
51281 #if defined(PERFETTO_HAS_CHMOD)
51282     // Passing 0644 directly above won't work because of umask.
51283     PERFETTO_CHECK(fchmod(*fd, 0644) == 0);
51284 #endif
51285   } else {
51286     PERFETTO_PLOG("Failed to create %s", path.c_str());
51287   }
51288   return fd;
51289 }
51290 
GetBugreportTmpPath()51291 std::string GetBugreportTmpPath() {
51292   return GetBugreportPath() + ".tmp";
51293 }
51294 
ShouldLogEvent(const TraceConfig & cfg)51295 bool ShouldLogEvent(const TraceConfig& cfg) {
51296   switch (cfg.statsd_logging()) {
51297     case TraceConfig::STATSD_LOGGING_ENABLED:
51298       return true;
51299     case TraceConfig::STATSD_LOGGING_DISABLED:
51300       return false;
51301     case TraceConfig::STATSD_LOGGING_UNSPECIFIED:
51302       // For backward compatibility with older versions of perfetto_cmd.
51303       return cfg.enable_extra_guardrails();
51304   }
51305   PERFETTO_FATAL("For GCC");
51306 }
51307 
51308 }  // namespace
51309 
51310 // These constants instead are defined in the header because are used by tests.
51311 constexpr size_t TracingServiceImpl::kDefaultShmSize;
51312 constexpr size_t TracingServiceImpl::kDefaultShmPageSize;
51313 
51314 constexpr size_t TracingServiceImpl::kMaxShmSize;
51315 constexpr uint32_t TracingServiceImpl::kDataSourceStopTimeoutMs;
51316 constexpr uint8_t TracingServiceImpl::kSyncMarker[];
51317 
GetBugreportPath()51318 std::string GetBugreportPath() {
51319 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
51320     PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
51321   return kAndroidProductionBugreportTracePath;
51322 #else
51323   // Only for tests, SaveTraceForBugreport is not used on other OSes.
51324   return base::GetSysTempDir() + "/bugreport.pftrace";
51325 #endif
51326 }
51327 
51328 // static
CreateInstance(std::unique_ptr<SharedMemory::Factory> shm_factory,base::TaskRunner * task_runner)51329 std::unique_ptr<TracingService> TracingService::CreateInstance(
51330     std::unique_ptr<SharedMemory::Factory> shm_factory,
51331     base::TaskRunner* task_runner) {
51332   return std::unique_ptr<TracingService>(
51333       new TracingServiceImpl(std::move(shm_factory), task_runner));
51334 }
51335 
TracingServiceImpl(std::unique_ptr<SharedMemory::Factory> shm_factory,base::TaskRunner * task_runner)51336 TracingServiceImpl::TracingServiceImpl(
51337     std::unique_ptr<SharedMemory::Factory> shm_factory,
51338     base::TaskRunner* task_runner)
51339     : task_runner_(task_runner),
51340       shm_factory_(std::move(shm_factory)),
51341       uid_(base::GetCurrentUserId()),
51342       buffer_ids_(kMaxTraceBufferID),
51343       trigger_probability_rand_(
51344           static_cast<uint32_t>(base::GetWallTimeNs().count())),
51345       weak_ptr_factory_(this) {
51346   PERFETTO_DCHECK(task_runner_);
51347 }
51348 
~TracingServiceImpl()51349 TracingServiceImpl::~TracingServiceImpl() {
51350   // TODO(fmayer): handle teardown of all Producer.
51351 }
51352 
51353 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,const std::string & sdk_version)51354 TracingServiceImpl::ConnectProducer(Producer* producer,
51355                                     uid_t uid,
51356                                     const std::string& producer_name,
51357                                     size_t shared_memory_size_hint_bytes,
51358                                     bool in_process,
51359                                     ProducerSMBScrapingMode smb_scraping_mode,
51360                                     size_t shared_memory_page_size_hint_bytes,
51361                                     std::unique_ptr<SharedMemory> shm,
51362                                     const std::string& sdk_version) {
51363   PERFETTO_DCHECK_THREAD(thread_checker_);
51364 
51365   if (lockdown_mode_ && uid != base::GetCurrentUserId()) {
51366     PERFETTO_DLOG("Lockdown mode. Rejecting producer with UID %ld",
51367                   static_cast<unsigned long>(uid));
51368     return nullptr;
51369   }
51370 
51371   if (producers_.size() >= kMaxProducerID) {
51372     PERFETTO_DFATAL("Too many producers.");
51373     return nullptr;
51374   }
51375   const ProducerID id = GetNextProducerID();
51376   PERFETTO_DLOG("Producer %" PRIu16 " connected", id);
51377 
51378   bool smb_scraping_enabled = smb_scraping_enabled_;
51379   switch (smb_scraping_mode) {
51380     case ProducerSMBScrapingMode::kDefault:
51381       break;
51382     case ProducerSMBScrapingMode::kEnabled:
51383       smb_scraping_enabled = true;
51384       break;
51385     case ProducerSMBScrapingMode::kDisabled:
51386       smb_scraping_enabled = false;
51387       break;
51388   }
51389 
51390   std::unique_ptr<ProducerEndpointImpl> endpoint(new ProducerEndpointImpl(
51391       id, uid, this, task_runner_, producer, producer_name, sdk_version,
51392       in_process, smb_scraping_enabled));
51393   auto it_and_inserted = producers_.emplace(id, endpoint.get());
51394   PERFETTO_DCHECK(it_and_inserted.second);
51395   endpoint->shmem_size_hint_bytes_ = shared_memory_size_hint_bytes;
51396   endpoint->shmem_page_size_hint_bytes_ = shared_memory_page_size_hint_bytes;
51397 
51398   // Producer::OnConnect() should run before Producer::OnTracingSetup(). The
51399   // latter may be posted by SetupSharedMemory() below, so post OnConnect() now.
51400   auto weak_ptr = endpoint->weak_ptr_factory_.GetWeakPtr();
51401   task_runner_->PostTask([weak_ptr] {
51402     if (weak_ptr)
51403       weak_ptr->producer_->OnConnect();
51404   });
51405 
51406   if (shm) {
51407     // The producer supplied an SMB. This is used only by Chrome; in the most
51408     // common cases the SMB is created by the service and passed via
51409     // OnTracingSetup(). Verify that it is correctly sized before we attempt to
51410     // use it. The transport layer has to verify the integrity of the SMB (e.g.
51411     // ensure that the producer can't resize if after the fact).
51412     size_t shm_size, page_size;
51413     std::tie(shm_size, page_size) =
51414         EnsureValidShmSizes(shm->size(), endpoint->shmem_page_size_hint_bytes_);
51415     if (shm_size == shm->size() &&
51416         page_size == endpoint->shmem_page_size_hint_bytes_) {
51417       PERFETTO_DLOG(
51418           "Adopting producer-provided SMB of %zu kB for producer \"%s\"",
51419           shm_size / 1024, endpoint->name_.c_str());
51420       endpoint->SetupSharedMemory(std::move(shm), page_size,
51421                                   /*provided_by_producer=*/true);
51422     } else {
51423       PERFETTO_LOG(
51424           "Discarding incorrectly sized producer-provided SMB for producer "
51425           "\"%s\", falling back to service-provided SMB. Requested sizes: %zu "
51426           "B total, %zu B page size; suggested corrected sizes: %zu B total, "
51427           "%zu B page size",
51428           endpoint->name_.c_str(), shm->size(),
51429           endpoint->shmem_page_size_hint_bytes_, shm_size, page_size);
51430       shm.reset();
51431     }
51432   }
51433 
51434   return std::unique_ptr<ProducerEndpoint>(std::move(endpoint));
51435 }
51436 
DisconnectProducer(ProducerID id)51437 void TracingServiceImpl::DisconnectProducer(ProducerID id) {
51438   PERFETTO_DCHECK_THREAD(thread_checker_);
51439   PERFETTO_DLOG("Producer %" PRIu16 " disconnected", id);
51440   PERFETTO_DCHECK(producers_.count(id));
51441 
51442   // Scrape remaining chunks for this producer to ensure we don't lose data.
51443   if (auto* producer = GetProducer(id)) {
51444     for (auto& session_id_and_session : tracing_sessions_)
51445       ScrapeSharedMemoryBuffers(&session_id_and_session.second, producer);
51446   }
51447 
51448   for (auto it = data_sources_.begin(); it != data_sources_.end();) {
51449     auto next = it;
51450     next++;
51451     if (it->second.producer_id == id)
51452       UnregisterDataSource(id, it->second.descriptor.name());
51453     it = next;
51454   }
51455 
51456   producers_.erase(id);
51457   UpdateMemoryGuardrail();
51458 }
51459 
GetProducer(ProducerID id) const51460 TracingServiceImpl::ProducerEndpointImpl* TracingServiceImpl::GetProducer(
51461     ProducerID id) const {
51462   PERFETTO_DCHECK_THREAD(thread_checker_);
51463   auto it = producers_.find(id);
51464   if (it == producers_.end())
51465     return nullptr;
51466   return it->second;
51467 }
51468 
51469 std::unique_ptr<TracingService::ConsumerEndpoint>
ConnectConsumer(Consumer * consumer,uid_t uid)51470 TracingServiceImpl::ConnectConsumer(Consumer* consumer, uid_t uid) {
51471   PERFETTO_DCHECK_THREAD(thread_checker_);
51472   PERFETTO_DLOG("Consumer %p connected from UID %" PRIu64,
51473                 reinterpret_cast<void*>(consumer), static_cast<uint64_t>(uid));
51474   std::unique_ptr<ConsumerEndpointImpl> endpoint(
51475       new ConsumerEndpointImpl(this, task_runner_, consumer, uid));
51476   auto it_and_inserted = consumers_.emplace(endpoint.get());
51477   PERFETTO_DCHECK(it_and_inserted.second);
51478   // Consumer might go away before we're able to send the connect notification,
51479   // if that is the case just bail out.
51480   auto weak_ptr = endpoint->weak_ptr_factory_.GetWeakPtr();
51481   task_runner_->PostTask([weak_ptr] {
51482     if (weak_ptr)
51483       weak_ptr->consumer_->OnConnect();
51484   });
51485   return std::unique_ptr<ConsumerEndpoint>(std::move(endpoint));
51486 }
51487 
DisconnectConsumer(ConsumerEndpointImpl * consumer)51488 void TracingServiceImpl::DisconnectConsumer(ConsumerEndpointImpl* consumer) {
51489   PERFETTO_DCHECK_THREAD(thread_checker_);
51490   PERFETTO_DLOG("Consumer %p disconnected", reinterpret_cast<void*>(consumer));
51491   PERFETTO_DCHECK(consumers_.count(consumer));
51492 
51493   // TODO(primiano) : Check that this is safe (what happens if there are
51494   // ReadBuffers() calls posted in the meantime? They need to become noop).
51495   if (consumer->tracing_session_id_)
51496     FreeBuffers(consumer->tracing_session_id_);  // Will also DisableTracing().
51497   consumers_.erase(consumer);
51498 
51499   // At this point no more pointers to |consumer| should be around.
51500   PERFETTO_DCHECK(!std::any_of(
51501       tracing_sessions_.begin(), tracing_sessions_.end(),
51502       [consumer](const std::pair<const TracingSessionID, TracingSession>& kv) {
51503         return kv.second.consumer_maybe_null == consumer;
51504       }));
51505 }
51506 
DetachConsumer(ConsumerEndpointImpl * consumer,const std::string & key)51507 bool TracingServiceImpl::DetachConsumer(ConsumerEndpointImpl* consumer,
51508                                         const std::string& key) {
51509   PERFETTO_DCHECK_THREAD(thread_checker_);
51510   PERFETTO_DLOG("Consumer %p detached", reinterpret_cast<void*>(consumer));
51511   PERFETTO_DCHECK(consumers_.count(consumer));
51512 
51513   TracingSessionID tsid = consumer->tracing_session_id_;
51514   TracingSession* tracing_session;
51515   if (!tsid || !(tracing_session = GetTracingSession(tsid)))
51516     return false;
51517 
51518   if (GetDetachedSession(consumer->uid_, key)) {
51519     PERFETTO_ELOG("Another session has been detached with the same key \"%s\"",
51520                   key.c_str());
51521     return false;
51522   }
51523 
51524   PERFETTO_DCHECK(tracing_session->consumer_maybe_null == consumer);
51525   tracing_session->consumer_maybe_null = nullptr;
51526   tracing_session->detach_key = key;
51527   consumer->tracing_session_id_ = 0;
51528   return true;
51529 }
51530 
AttachConsumer(ConsumerEndpointImpl * consumer,const std::string & key)51531 bool TracingServiceImpl::AttachConsumer(ConsumerEndpointImpl* consumer,
51532                                         const std::string& key) {
51533   PERFETTO_DCHECK_THREAD(thread_checker_);
51534   PERFETTO_DLOG("Consumer %p attaching to session %s",
51535                 reinterpret_cast<void*>(consumer), key.c_str());
51536   PERFETTO_DCHECK(consumers_.count(consumer));
51537 
51538   if (consumer->tracing_session_id_) {
51539     PERFETTO_ELOG(
51540         "Cannot reattach consumer to session %s"
51541         " while it already attached tracing session ID %" PRIu64,
51542         key.c_str(), consumer->tracing_session_id_);
51543     return false;
51544   }
51545 
51546   auto* tracing_session = GetDetachedSession(consumer->uid_, key);
51547   if (!tracing_session) {
51548     PERFETTO_ELOG(
51549         "Failed to attach consumer, session '%s' not found for uid %d",
51550         key.c_str(), static_cast<int>(consumer->uid_));
51551     return false;
51552   }
51553 
51554   consumer->tracing_session_id_ = tracing_session->id;
51555   tracing_session->consumer_maybe_null = consumer;
51556   tracing_session->detach_key.clear();
51557   return true;
51558 }
51559 
EnableTracing(ConsumerEndpointImpl * consumer,const TraceConfig & cfg,base::ScopedFile fd)51560 base::Status TracingServiceImpl::EnableTracing(ConsumerEndpointImpl* consumer,
51561                                                const TraceConfig& cfg,
51562                                                base::ScopedFile fd) {
51563   PERFETTO_DCHECK_THREAD(thread_checker_);
51564   PERFETTO_DLOG("Enabling tracing for consumer %p",
51565                 reinterpret_cast<void*>(consumer));
51566   MaybeLogUploadEvent(cfg, PerfettoStatsdAtom::kTracedEnableTracing);
51567   if (cfg.lockdown_mode() == TraceConfig::LOCKDOWN_SET)
51568     lockdown_mode_ = true;
51569   if (cfg.lockdown_mode() == TraceConfig::LOCKDOWN_CLEAR)
51570     lockdown_mode_ = false;
51571 
51572   // Scope |tracing_session| to this block to prevent accidental use of a null
51573   // pointer later in this function.
51574   {
51575     TracingSession* tracing_session =
51576         GetTracingSession(consumer->tracing_session_id_);
51577     if (tracing_session) {
51578       MaybeLogUploadEvent(
51579           cfg, PerfettoStatsdAtom::kTracedEnableTracingExistingTraceSession);
51580       return PERFETTO_SVC_ERR(
51581           "A Consumer is trying to EnableTracing() but another tracing "
51582           "session is already active (forgot a call to FreeBuffers() ?)");
51583     }
51584   }
51585 
51586   const uint32_t max_duration_ms = cfg.enable_extra_guardrails()
51587                                        ? kGuardrailsMaxTracingDurationMillis
51588                                        : kMaxTracingDurationMillis;
51589   if (cfg.duration_ms() > max_duration_ms) {
51590     MaybeLogUploadEvent(cfg,
51591                         PerfettoStatsdAtom::kTracedEnableTracingTooLongTrace);
51592     return PERFETTO_SVC_ERR("Requested too long trace (%" PRIu32
51593                             "ms  > %" PRIu32 " ms)",
51594                             cfg.duration_ms(), max_duration_ms);
51595   }
51596 
51597   const bool has_trigger_config = cfg.trigger_config().trigger_mode() !=
51598                                   TraceConfig::TriggerConfig::UNSPECIFIED;
51599   if (has_trigger_config && (cfg.trigger_config().trigger_timeout_ms() == 0 ||
51600                              cfg.trigger_config().trigger_timeout_ms() >
51601                                  kGuardrailsMaxTracingDurationMillis)) {
51602     MaybeLogUploadEvent(
51603         cfg, PerfettoStatsdAtom::kTracedEnableTracingInvalidTriggerTimeout);
51604     return PERFETTO_SVC_ERR(
51605         "Traces with START_TRACING triggers must provide a positive "
51606         "trigger_timeout_ms < 7 days (received %" PRIu32 "ms)",
51607         cfg.trigger_config().trigger_timeout_ms());
51608   }
51609 
51610   if (has_trigger_config && cfg.duration_ms() != 0) {
51611     MaybeLogUploadEvent(
51612         cfg, PerfettoStatsdAtom::kTracedEnableTracingDurationWithTrigger);
51613     return PERFETTO_SVC_ERR(
51614         "duration_ms was set, this must not be set for traces with triggers.");
51615   }
51616 
51617   if (cfg.trigger_config().trigger_mode() ==
51618           TraceConfig::TriggerConfig::STOP_TRACING &&
51619       cfg.write_into_file()) {
51620     // We don't support this usecase because there are subtle assumptions which
51621     // break around TracingServiceEvents and windowed sorting (i.e. if we don't
51622     // drain the events in ReadBuffers because we are waiting for STOP_TRACING,
51623     // we can end up queueing up a lot of TracingServiceEvents and emitting them
51624     // wildy out of order breaking windowed sorting in trace processor).
51625     MaybeLogUploadEvent(
51626         cfg, PerfettoStatsdAtom::kTracedEnableTracingStopTracingWriteIntoFile);
51627     return PERFETTO_SVC_ERR(
51628         "Specifying trigger mode STOP_TRACING and write_into_file together is "
51629         "unsupported");
51630   }
51631 
51632   std::unordered_set<std::string> triggers;
51633   for (const auto& trigger : cfg.trigger_config().triggers()) {
51634     if (!triggers.insert(trigger.name()).second) {
51635       MaybeLogUploadEvent(
51636           cfg, PerfettoStatsdAtom::kTracedEnableTracingDuplicateTriggerName);
51637       return PERFETTO_SVC_ERR("Duplicate trigger name: %s",
51638                               trigger.name().c_str());
51639     }
51640   }
51641 
51642   if (cfg.enable_extra_guardrails()) {
51643     if (cfg.deferred_start()) {
51644       MaybeLogUploadEvent(
51645           cfg, PerfettoStatsdAtom::kTracedEnableTracingInvalidDeferredStart);
51646       return PERFETTO_SVC_ERR(
51647           "deferred_start=true is not supported in unsupervised traces");
51648     }
51649     uint64_t buf_size_sum = 0;
51650     for (const auto& buf : cfg.buffers()) {
51651       if (buf.size_kb() % 4 != 0) {
51652         MaybeLogUploadEvent(
51653             cfg, PerfettoStatsdAtom::kTracedEnableTracingInvalidBufferSize);
51654         return PERFETTO_SVC_ERR(
51655             "buffers.size_kb must be a multiple of 4, got %" PRIu32,
51656             buf.size_kb());
51657       }
51658       buf_size_sum += buf.size_kb();
51659     }
51660     if (buf_size_sum > kGuardrailsMaxTracingBufferSizeKb) {
51661       MaybeLogUploadEvent(
51662           cfg, PerfettoStatsdAtom::kTracedEnableTracingBufferSizeTooLarge);
51663       return PERFETTO_SVC_ERR("Requested too large trace buffer (%" PRIu64
51664                               "kB  > %" PRIu32 " kB)",
51665                               buf_size_sum, kGuardrailsMaxTracingBufferSizeKb);
51666     }
51667   }
51668 
51669   if (cfg.buffers_size() > kMaxBuffersPerConsumer) {
51670     MaybeLogUploadEvent(cfg,
51671                         PerfettoStatsdAtom::kTracedEnableTracingTooManyBuffers);
51672     return PERFETTO_SVC_ERR("Too many buffers configured (%d)",
51673                             cfg.buffers_size());
51674   }
51675 
51676   if (!cfg.unique_session_name().empty()) {
51677     const std::string& name = cfg.unique_session_name();
51678     for (auto& kv : tracing_sessions_) {
51679       if (kv.second.config.unique_session_name() == name) {
51680         MaybeLogUploadEvent(
51681             cfg, PerfettoStatsdAtom::kTracedEnableTracingDuplicateSessionName);
51682         static const char fmt[] =
51683             "A trace with this unique session name (%s) already exists";
51684         // This happens frequently, don't make it an "E"LOG.
51685         PERFETTO_LOG(fmt, name.c_str());
51686         return base::ErrStatus(fmt, name.c_str());
51687       }
51688     }
51689   }
51690 
51691   if (cfg.enable_extra_guardrails()) {
51692     // unique_session_name can be empty
51693     const std::string& name = cfg.unique_session_name();
51694     int64_t now_s = base::GetBootTimeS().count();
51695 
51696     // Remove any entries where the time limit has passed so this map doesn't
51697     // grow indefinitely:
51698     std::map<std::string, int64_t>& sessions = session_to_last_trace_s_;
51699     for (auto it = sessions.cbegin(); it != sessions.cend();) {
51700       if (now_s - it->second > kMinSecondsBetweenTracesGuardrail) {
51701         it = sessions.erase(it);
51702       } else {
51703         ++it;
51704       }
51705     }
51706 
51707     int64_t& previous_s = session_to_last_trace_s_[name];
51708     if (previous_s == 0) {
51709       previous_s = now_s;
51710     } else {
51711       MaybeLogUploadEvent(
51712           cfg, PerfettoStatsdAtom::kTracedEnableTracingSessionNameTooRecent);
51713       return PERFETTO_SVC_ERR(
51714           "A trace with unique session name \"%s\" began less than %" PRId64
51715           "s ago (%" PRId64 "s)",
51716           name.c_str(), kMinSecondsBetweenTracesGuardrail, now_s - previous_s);
51717     }
51718   }
51719 
51720   const int sessions_for_uid = static_cast<int>(std::count_if(
51721       tracing_sessions_.begin(), tracing_sessions_.end(),
51722       [consumer](const decltype(tracing_sessions_)::value_type& s) {
51723         return s.second.consumer_uid == consumer->uid_;
51724       }));
51725 
51726   int per_uid_limit = kMaxConcurrentTracingSessionsPerUid;
51727   if (consumer->uid_ == 1066 /* AID_STATSD*/) {
51728     per_uid_limit = kMaxConcurrentTracingSessionsForStatsdUid;
51729   }
51730   if (sessions_for_uid >= per_uid_limit) {
51731     MaybeLogUploadEvent(
51732         cfg, PerfettoStatsdAtom::kTracedEnableTracingTooManySessionsForUid);
51733     return PERFETTO_SVC_ERR(
51734         "Too many concurrent tracing sesions (%d) for uid %d limit is %d",
51735         sessions_for_uid, static_cast<int>(consumer->uid_), per_uid_limit);
51736   }
51737 
51738   // TODO(primiano): This is a workaround to prevent that a producer gets stuck
51739   // in a state where it stalls by design by having more TraceWriterImpl
51740   // instances than free pages in the buffer. This is really a bug in
51741   // trace_probes and the way it handles stalls in the shmem buffer.
51742   if (tracing_sessions_.size() >= kMaxConcurrentTracingSessions) {
51743     MaybeLogUploadEvent(
51744         cfg, PerfettoStatsdAtom::kTracedEnableTracingTooManyConcurrentSessions);
51745     return PERFETTO_SVC_ERR("Too many concurrent tracing sesions (%zu)",
51746                             tracing_sessions_.size());
51747   }
51748 
51749   // If the trace config provides a filter bytecode, setup the filter now.
51750   // If the filter loading fails, abort the tracing session rather than running
51751   // unfiltered.
51752   std::unique_ptr<protozero::MessageFilter> trace_filter;
51753   if (cfg.has_trace_filter()) {
51754     const auto& filt = cfg.trace_filter();
51755     const std::string& bytecode = filt.bytecode();
51756     trace_filter.reset(new protozero::MessageFilter());
51757     if (!trace_filter->LoadFilterBytecode(bytecode.data(), bytecode.size())) {
51758       MaybeLogUploadEvent(
51759           cfg, PerfettoStatsdAtom::kTracedEnableTracingInvalidFilter);
51760       return PERFETTO_SVC_ERR("Trace filter bytecode invalid, aborting");
51761     }
51762     // The filter is created using perfetto.protos.Trace as root message
51763     // (because that makes it possible to play around with the `proto_filter`
51764     // tool on actual traces). Here in the service, however, we deal with
51765     // perfetto.protos.TracePacket(s), which are one level down (Trace.packet).
51766     // The IPC client (or the write_into_filte logic in here) are responsible
51767     // for pre-pending the packet preamble (See GetProtoPreamble() calls), but
51768     // the preamble is not there at ReadBuffer time. Hence we change the root of
51769     // the filtering to start at the Trace.packet level.
51770     uint32_t packet_field_id = TracePacket::kPacketFieldNumber;
51771     if (!trace_filter->SetFilterRoot(&packet_field_id, 1)) {
51772       MaybeLogUploadEvent(
51773           cfg, PerfettoStatsdAtom::kTracedEnableTracingInvalidFilter);
51774       return PERFETTO_SVC_ERR("Failed to set filter root.");
51775     }
51776   }
51777 
51778   const TracingSessionID tsid = ++last_tracing_session_id_;
51779   TracingSession* tracing_session =
51780       &tracing_sessions_
51781            .emplace(std::piecewise_construct, std::forward_as_tuple(tsid),
51782                     std::forward_as_tuple(tsid, consumer, cfg, task_runner_))
51783            .first->second;
51784 
51785   if (trace_filter)
51786     tracing_session->trace_filter = std::move(trace_filter);
51787 
51788   if (cfg.write_into_file()) {
51789     if (!fd ^ !cfg.output_path().empty()) {
51790       tracing_sessions_.erase(tsid);
51791       MaybeLogUploadEvent(
51792           tracing_session->config,
51793           PerfettoStatsdAtom::kTracedEnableTracingInvalidFdOutputFile);
51794       return PERFETTO_SVC_ERR(
51795           "When write_into_file==true either a FD needs to be passed or "
51796           "output_path must be populated (but not both)");
51797     }
51798     if (!cfg.output_path().empty()) {
51799       fd = CreateTraceFile(cfg.output_path(), /*overwrite=*/false);
51800       if (!fd) {
51801         MaybeLogUploadEvent(
51802             tracing_session->config,
51803             PerfettoStatsdAtom::kTracedEnableTracingFailedToCreateFile);
51804         tracing_sessions_.erase(tsid);
51805         return PERFETTO_SVC_ERR("Failed to create the trace file %s",
51806                                 cfg.output_path().c_str());
51807       }
51808     }
51809     tracing_session->write_into_file = std::move(fd);
51810     uint32_t write_period_ms = cfg.file_write_period_ms();
51811     if (write_period_ms == 0)
51812       write_period_ms = kDefaultWriteIntoFilePeriodMs;
51813     if (write_period_ms < min_write_period_ms_)
51814       write_period_ms = min_write_period_ms_;
51815     tracing_session->write_period_ms = write_period_ms;
51816     tracing_session->max_file_size_bytes = cfg.max_file_size_bytes();
51817     tracing_session->bytes_written_into_file = 0;
51818   }
51819 
51820   // Initialize the log buffers.
51821   bool did_allocate_all_buffers = true;
51822 
51823   // Allocate the trace buffers. Also create a map to translate a consumer
51824   // relative index (TraceConfig.DataSourceConfig.target_buffer) into the
51825   // corresponding BufferID, which is a global ID namespace for the service and
51826   // all producers.
51827   size_t total_buf_size_kb = 0;
51828   const size_t num_buffers = static_cast<size_t>(cfg.buffers_size());
51829   tracing_session->buffers_index.reserve(num_buffers);
51830   for (size_t i = 0; i < num_buffers; i++) {
51831     const TraceConfig::BufferConfig& buffer_cfg = cfg.buffers()[i];
51832     BufferID global_id = buffer_ids_.Allocate();
51833     if (!global_id) {
51834       did_allocate_all_buffers = false;  // We ran out of IDs.
51835       break;
51836     }
51837     tracing_session->buffers_index.push_back(global_id);
51838     const size_t buf_size_bytes = buffer_cfg.size_kb() * 1024u;
51839     total_buf_size_kb += buffer_cfg.size_kb();
51840     TraceBuffer::OverwritePolicy policy =
51841         buffer_cfg.fill_policy() == TraceConfig::BufferConfig::DISCARD
51842             ? TraceBuffer::kDiscard
51843             : TraceBuffer::kOverwrite;
51844     auto it_and_inserted = buffers_.emplace(
51845         global_id, TraceBuffer::Create(buf_size_bytes, policy));
51846     PERFETTO_DCHECK(it_and_inserted.second);  // buffers_.count(global_id) == 0.
51847     std::unique_ptr<TraceBuffer>& trace_buffer = it_and_inserted.first->second;
51848     if (!trace_buffer) {
51849       did_allocate_all_buffers = false;
51850       break;
51851     }
51852   }
51853 
51854   UpdateMemoryGuardrail();
51855 
51856   // This can happen if either:
51857   // - All the kMaxTraceBufferID slots are taken.
51858   // - OOM, or, more relistically, we exhausted virtual memory.
51859   // In any case, free all the previously allocated buffers and abort.
51860   // TODO(fmayer): add a test to cover this case, this is quite subtle.
51861   if (!did_allocate_all_buffers) {
51862     for (BufferID global_id : tracing_session->buffers_index) {
51863       buffer_ids_.Free(global_id);
51864       buffers_.erase(global_id);
51865     }
51866     tracing_sessions_.erase(tsid);
51867     MaybeLogUploadEvent(tracing_session->config,
51868                         PerfettoStatsdAtom::kTracedEnableTracingOom);
51869     return PERFETTO_SVC_ERR(
51870         "Failed to allocate tracing buffers: OOM or too many buffers");
51871   }
51872 
51873   consumer->tracing_session_id_ = tsid;
51874 
51875   // Setup the data sources on the producers without starting them.
51876   for (const TraceConfig::DataSource& cfg_data_source : cfg.data_sources()) {
51877     // Scan all the registered data sources with a matching name.
51878     auto range = data_sources_.equal_range(cfg_data_source.config().name());
51879     for (auto it = range.first; it != range.second; it++) {
51880       TraceConfig::ProducerConfig producer_config;
51881       for (auto& config : cfg.producers()) {
51882         if (GetProducer(it->second.producer_id)->name_ ==
51883             config.producer_name()) {
51884           producer_config = config;
51885           break;
51886         }
51887       }
51888       SetupDataSource(cfg_data_source, producer_config, it->second,
51889                       tracing_session);
51890     }
51891   }
51892 
51893   bool has_start_trigger = false;
51894   auto weak_this = weak_ptr_factory_.GetWeakPtr();
51895   switch (cfg.trigger_config().trigger_mode()) {
51896     case TraceConfig::TriggerConfig::UNSPECIFIED:
51897       // no triggers are specified so this isn't a trace that is using triggers.
51898       PERFETTO_DCHECK(!has_trigger_config);
51899       break;
51900     case TraceConfig::TriggerConfig::START_TRACING:
51901       // For traces which use START_TRACE triggers we need to ensure that the
51902       // tracing session will be cleaned up when it times out.
51903       has_start_trigger = true;
51904       task_runner_->PostDelayedTask(
51905           [weak_this, tsid]() {
51906             if (weak_this)
51907               weak_this->OnStartTriggersTimeout(tsid);
51908           },
51909           cfg.trigger_config().trigger_timeout_ms());
51910       break;
51911     case TraceConfig::TriggerConfig::STOP_TRACING:
51912       // Update the tracing_session's duration_ms to ensure that if no trigger
51913       // is received the session will end and be cleaned up equal to the
51914       // timeout.
51915       //
51916       // TODO(nuskos): Refactor this so that rather then modifying the config we
51917       // have a field we look at on the tracing_session.
51918       tracing_session->config.set_duration_ms(
51919           cfg.trigger_config().trigger_timeout_ms());
51920       break;
51921   }
51922 
51923   tracing_session->state = TracingSession::CONFIGURED;
51924   PERFETTO_LOG(
51925       "Configured tracing session %" PRIu64
51926       ", #sources:%zu, duration:%d ms, #buffers:%d, total "
51927       "buffer size:%zu KB, total sessions:%zu, uid:%d session name: \"%s\"",
51928       tsid, cfg.data_sources().size(), tracing_session->config.duration_ms(),
51929       cfg.buffers_size(), total_buf_size_kb, tracing_sessions_.size(),
51930       static_cast<unsigned int>(consumer->uid_),
51931       cfg.unique_session_name().c_str());
51932 
51933   // Start the data sources, unless this is a case of early setup + fast
51934   // triggering, either through TraceConfig.deferred_start or
51935   // TraceConfig.trigger_config(). If both are specified which ever one occurs
51936   // first will initiate the trace.
51937   if (!cfg.deferred_start() && !has_start_trigger)
51938     return StartTracing(tsid);
51939 
51940   return base::OkStatus();
51941 }
51942 
ChangeTraceConfig(ConsumerEndpointImpl * consumer,const TraceConfig & updated_cfg)51943 void TracingServiceImpl::ChangeTraceConfig(ConsumerEndpointImpl* consumer,
51944                                            const TraceConfig& updated_cfg) {
51945   PERFETTO_DCHECK_THREAD(thread_checker_);
51946   TracingSession* tracing_session =
51947       GetTracingSession(consumer->tracing_session_id_);
51948   PERFETTO_DCHECK(tracing_session);
51949 
51950   if ((tracing_session->state != TracingSession::STARTED) &&
51951       (tracing_session->state != TracingSession::CONFIGURED)) {
51952     PERFETTO_ELOG(
51953         "ChangeTraceConfig() was called for a tracing session which isn't "
51954         "running.");
51955     return;
51956   }
51957 
51958   // We only support updating producer_name_{,regex}_filter (and pass-through
51959   // configs) for now; null out any changeable fields and make sure the rest are
51960   // identical.
51961   TraceConfig new_config_copy(updated_cfg);
51962   for (auto& ds_cfg : *new_config_copy.mutable_data_sources()) {
51963     ds_cfg.clear_producer_name_filter();
51964     ds_cfg.clear_producer_name_regex_filter();
51965   }
51966 
51967   TraceConfig current_config_copy(tracing_session->config);
51968   for (auto& ds_cfg : *current_config_copy.mutable_data_sources()) {
51969     ds_cfg.clear_producer_name_filter();
51970     ds_cfg.clear_producer_name_regex_filter();
51971   }
51972 
51973   if (new_config_copy != current_config_copy) {
51974     PERFETTO_LOG(
51975         "ChangeTraceConfig() was called with a config containing unsupported "
51976         "changes; only adding to the producer_name_{,regex}_filter is "
51977         "currently supported and will have an effect.");
51978   }
51979 
51980   for (TraceConfig::DataSource& cfg_data_source :
51981        *tracing_session->config.mutable_data_sources()) {
51982     // Find the updated producer_filter in the new config.
51983     std::vector<std::string> new_producer_name_filter;
51984     std::vector<std::string> new_producer_name_regex_filter;
51985     bool found_data_source = false;
51986     for (const auto& it : updated_cfg.data_sources()) {
51987       if (cfg_data_source.config().name() == it.config().name()) {
51988         new_producer_name_filter = it.producer_name_filter();
51989         new_producer_name_regex_filter = it.producer_name_regex_filter();
51990         found_data_source = true;
51991         break;
51992       }
51993     }
51994 
51995     // Bail out if data source not present in the new config.
51996     if (!found_data_source) {
51997       PERFETTO_ELOG(
51998           "ChangeTraceConfig() called without a current data source also "
51999           "present in the new config: %s",
52000           cfg_data_source.config().name().c_str());
52001       continue;
52002     }
52003 
52004     // TODO(oysteine): Just replacing the filter means that if
52005     // there are any filter entries which were present in the original config,
52006     // but removed from the config passed to ChangeTraceConfig, any matching
52007     // producers will keep producing but newly added producers after this
52008     // point will never start.
52009     *cfg_data_source.mutable_producer_name_filter() = new_producer_name_filter;
52010     *cfg_data_source.mutable_producer_name_regex_filter() =
52011         new_producer_name_regex_filter;
52012 
52013     // Scan all the registered data sources with a matching name.
52014     auto range = data_sources_.equal_range(cfg_data_source.config().name());
52015     for (auto it = range.first; it != range.second; it++) {
52016       ProducerEndpointImpl* producer = GetProducer(it->second.producer_id);
52017       PERFETTO_DCHECK(producer);
52018 
52019       // Check if the producer name of this data source is present
52020       // in the name filters. We currently only support new filters, not
52021       // removing old ones.
52022       if (!NameMatchesFilter(producer->name_, new_producer_name_filter,
52023                              new_producer_name_regex_filter)) {
52024         continue;
52025       }
52026 
52027       bool already_setup = false;
52028       auto& ds_instances = tracing_session->data_source_instances;
52029       for (auto instance_it = ds_instances.begin();
52030            instance_it != ds_instances.end(); ++instance_it) {
52031         if (instance_it->first == it->second.producer_id &&
52032             instance_it->second.data_source_name ==
52033                 cfg_data_source.config().name()) {
52034           already_setup = true;
52035           break;
52036         }
52037       }
52038 
52039       if (already_setup)
52040         continue;
52041 
52042       // If it wasn't previously setup, set it up now.
52043       // (The per-producer config is optional).
52044       TraceConfig::ProducerConfig producer_config;
52045       for (auto& config : tracing_session->config.producers()) {
52046         if (producer->name_ == config.producer_name()) {
52047           producer_config = config;
52048           break;
52049         }
52050       }
52051 
52052       DataSourceInstance* ds_inst = SetupDataSource(
52053           cfg_data_source, producer_config, it->second, tracing_session);
52054 
52055       if (ds_inst && tracing_session->state == TracingSession::STARTED)
52056         StartDataSourceInstance(producer, tracing_session, ds_inst);
52057     }
52058   }
52059 }
52060 
StartTracing(TracingSessionID tsid)52061 base::Status TracingServiceImpl::StartTracing(TracingSessionID tsid) {
52062   PERFETTO_DCHECK_THREAD(thread_checker_);
52063 
52064   auto weak_this = weak_ptr_factory_.GetWeakPtr();
52065   TracingSession* tracing_session = GetTracingSession(tsid);
52066   if (!tracing_session) {
52067     return PERFETTO_SVC_ERR(
52068         "StartTracing() failed, invalid session ID %" PRIu64, tsid);
52069   }
52070 
52071   MaybeLogUploadEvent(tracing_session->config,
52072                       PerfettoStatsdAtom::kTracedStartTracing);
52073 
52074   if (tracing_session->state != TracingSession::CONFIGURED) {
52075     MaybeLogUploadEvent(
52076         tracing_session->config,
52077         PerfettoStatsdAtom::kTracedStartTracingInvalidSessionState);
52078     return PERFETTO_SVC_ERR("StartTracing() failed, invalid session state: %d",
52079                             tracing_session->state);
52080   }
52081 
52082   tracing_session->state = TracingSession::STARTED;
52083 
52084   // We store the start of trace snapshot separately as it's important to make
52085   // sure we can interpret all the data in the trace and storing it in the ring
52086   // buffer means it could be overwritten by a later snapshot.
52087   if (!tracing_session->config.builtin_data_sources()
52088            .disable_clock_snapshotting()) {
52089     SnapshotClocks(&tracing_session->initial_clock_snapshot);
52090   }
52091 
52092   // We don't snapshot the clocks here because we just did this above.
52093   SnapshotLifecyleEvent(
52094       tracing_session,
52095       protos::pbzero::TracingServiceEvent::kTracingStartedFieldNumber,
52096       false /* snapshot_clocks */);
52097 
52098   // Periodically snapshot clocks, stats, sync markers while the trace is
52099   // active. The snapshots are emitted on the future ReadBuffers() calls, which
52100   // means that:
52101   //  (a) If we're streaming to a file (or to a consumer) while tracing, we
52102   //      write snapshots periodically into the trace.
52103   //  (b) If ReadBuffers() is only called after tracing ends, we emit the latest
52104   //      snapshot into the trace. For clock snapshots, we keep track of the
52105   //      snapshot recorded at the beginning of the session
52106   //      (initial_clock_snapshot above), as well as the most recent sampled
52107   //      snapshots that showed significant new drift between different clocks.
52108   //      The latter clock snapshots are sampled periodically and at lifecycle
52109   //      events.
52110   base::PeriodicTask::Args snapshot_task_args;
52111   snapshot_task_args.start_first_task_immediately = true;
52112   snapshot_task_args.use_suspend_aware_timer =
52113       tracing_session->config.builtin_data_sources()
52114           .prefer_suspend_clock_for_snapshot();
52115   snapshot_task_args.task = [weak_this, tsid] {
52116     if (weak_this)
52117       weak_this->PeriodicSnapshotTask(tsid);
52118   };
52119   snapshot_task_args.period_ms =
52120       tracing_session->config.builtin_data_sources().snapshot_interval_ms();
52121   if (!snapshot_task_args.period_ms)
52122     snapshot_task_args.period_ms = kDefaultSnapshotsIntervalMs;
52123   tracing_session->snapshot_periodic_task.Start(snapshot_task_args);
52124 
52125   // Trigger delayed task if the trace is time limited.
52126   const uint32_t trace_duration_ms = tracing_session->config.duration_ms();
52127   if (trace_duration_ms > 0) {
52128     task_runner_->PostDelayedTask(
52129         [weak_this, tsid] {
52130           // Skip entirely the flush if the trace session doesn't exist anymore.
52131           // This is to prevent misleading error messages to be logged.
52132           if (!weak_this)
52133             return;
52134           auto* tracing_session_ptr = weak_this->GetTracingSession(tsid);
52135           if (!tracing_session_ptr)
52136             return;
52137           // If this trace was using STOP_TRACING triggers and we've seen
52138           // one, then the trigger overrides the normal timeout. In this
52139           // case we just return and let the other task clean up this trace.
52140           if (tracing_session_ptr->config.trigger_config().trigger_mode() ==
52141                   TraceConfig::TriggerConfig::STOP_TRACING &&
52142               !tracing_session_ptr->received_triggers.empty())
52143             return;
52144           // In all other cases (START_TRACING or no triggers) we flush
52145           // after |trace_duration_ms| unconditionally.
52146           weak_this->FlushAndDisableTracing(tsid);
52147         },
52148         trace_duration_ms);
52149   }
52150 
52151   // Start the periodic drain tasks if we should to save the trace into a file.
52152   if (tracing_session->config.write_into_file()) {
52153     task_runner_->PostDelayedTask(
52154         [weak_this, tsid] {
52155           if (weak_this)
52156             weak_this->ReadBuffers(tsid, nullptr);
52157         },
52158         tracing_session->delay_to_next_write_period_ms());
52159   }
52160 
52161   // Start the periodic flush tasks if the config specified a flush period.
52162   if (tracing_session->config.flush_period_ms())
52163     PeriodicFlushTask(tsid, /*post_next_only=*/true);
52164 
52165   // Start the periodic incremental state clear tasks if the config specified a
52166   // period.
52167   if (tracing_session->config.incremental_state_config().clear_period_ms()) {
52168     PeriodicClearIncrementalStateTask(tsid, /*post_next_only=*/true);
52169   }
52170 
52171   for (auto& kv : tracing_session->data_source_instances) {
52172     ProducerID producer_id = kv.first;
52173     DataSourceInstance& data_source = kv.second;
52174     ProducerEndpointImpl* producer = GetProducer(producer_id);
52175     if (!producer) {
52176       PERFETTO_DFATAL("Producer does not exist.");
52177       continue;
52178     }
52179     StartDataSourceInstance(producer, tracing_session, &data_source);
52180   }
52181 
52182   MaybeNotifyAllDataSourcesStarted(tracing_session);
52183   return base::OkStatus();
52184 }
52185 
StartDataSourceInstance(ProducerEndpointImpl * producer,TracingSession * tracing_session,TracingServiceImpl::DataSourceInstance * instance)52186 void TracingServiceImpl::StartDataSourceInstance(
52187     ProducerEndpointImpl* producer,
52188     TracingSession* tracing_session,
52189     TracingServiceImpl::DataSourceInstance* instance) {
52190   PERFETTO_DCHECK(instance->state == DataSourceInstance::CONFIGURED);
52191   if (instance->will_notify_on_start) {
52192     instance->state = DataSourceInstance::STARTING;
52193   } else {
52194     instance->state = DataSourceInstance::STARTED;
52195   }
52196   if (tracing_session->consumer_maybe_null) {
52197     tracing_session->consumer_maybe_null->OnDataSourceInstanceStateChange(
52198         *producer, *instance);
52199   }
52200   producer->StartDataSource(instance->instance_id, instance->config);
52201 
52202   // If all data sources are started, notify the consumer.
52203   if (instance->state == DataSourceInstance::STARTED)
52204     MaybeNotifyAllDataSourcesStarted(tracing_session);
52205 }
52206 
52207 // DisableTracing just stops the data sources but doesn't free up any buffer.
52208 // This is to allow the consumer to freeze the buffers (by stopping the trace)
52209 // and then drain the buffers. The actual teardown of the TracingSession happens
52210 // in FreeBuffers().
DisableTracing(TracingSessionID tsid,bool disable_immediately)52211 void TracingServiceImpl::DisableTracing(TracingSessionID tsid,
52212                                         bool disable_immediately) {
52213   PERFETTO_DCHECK_THREAD(thread_checker_);
52214   TracingSession* tracing_session = GetTracingSession(tsid);
52215   if (!tracing_session) {
52216     // Can happen if the consumer calls this before EnableTracing() or after
52217     // FreeBuffers().
52218     PERFETTO_DLOG("DisableTracing() failed, invalid session ID %" PRIu64, tsid);
52219     return;
52220   }
52221 
52222   MaybeLogUploadEvent(tracing_session->config,
52223                       PerfettoStatsdAtom::kTracedDisableTracing);
52224 
52225   switch (tracing_session->state) {
52226     // Spurious call to DisableTracing() while already disabled, nothing to do.
52227     case TracingSession::DISABLED:
52228       PERFETTO_DCHECK(tracing_session->AllDataSourceInstancesStopped());
52229       return;
52230 
52231     // This is either:
52232     // A) The case of a graceful DisableTracing() call followed by a call to
52233     //    FreeBuffers(), iff |disable_immediately| == true. In this case we want
52234     //    to forcefully transition in the disabled state without waiting for the
52235     //    outstanding acks because the buffers are going to be destroyed soon.
52236     // B) A spurious call, iff |disable_immediately| == false, in which case
52237     //    there is nothing to do.
52238     case TracingSession::DISABLING_WAITING_STOP_ACKS:
52239       PERFETTO_DCHECK(!tracing_session->AllDataSourceInstancesStopped());
52240       if (disable_immediately)
52241         DisableTracingNotifyConsumerAndFlushFile(tracing_session);
52242       return;
52243 
52244     // Continues below.
52245     case TracingSession::CONFIGURED:
52246       // If the session didn't even start there is no need to orchestrate a
52247       // graceful stop of data sources.
52248       disable_immediately = true;
52249       break;
52250 
52251     // This is the nominal case, continues below.
52252     case TracingSession::STARTED:
52253       break;
52254   }
52255 
52256   for (auto& data_source_inst : tracing_session->data_source_instances) {
52257     const ProducerID producer_id = data_source_inst.first;
52258     DataSourceInstance& instance = data_source_inst.second;
52259     ProducerEndpointImpl* producer = GetProducer(producer_id);
52260     PERFETTO_DCHECK(producer);
52261     PERFETTO_DCHECK(instance.state == DataSourceInstance::CONFIGURED ||
52262                     instance.state == DataSourceInstance::STARTING ||
52263                     instance.state == DataSourceInstance::STARTED);
52264     StopDataSourceInstance(producer, tracing_session, &instance,
52265                            disable_immediately);
52266   }
52267 
52268   // If the periodic task is running, we can stop the periodic snapshot timer
52269   // here instead of waiting until FreeBuffers to prevent useless snapshots
52270   // which won't be read.
52271   tracing_session->snapshot_periodic_task.Reset();
52272 
52273   // Either this request is flagged with |disable_immediately| or there are no
52274   // data sources that are requesting a final handshake. In both cases just mark
52275   // the session as disabled immediately, notify the consumer and flush the
52276   // trace file (if used).
52277   if (tracing_session->AllDataSourceInstancesStopped())
52278     return DisableTracingNotifyConsumerAndFlushFile(tracing_session);
52279 
52280   tracing_session->state = TracingSession::DISABLING_WAITING_STOP_ACKS;
52281   auto weak_this = weak_ptr_factory_.GetWeakPtr();
52282   task_runner_->PostDelayedTask(
52283       [weak_this, tsid] {
52284         if (weak_this)
52285           weak_this->OnDisableTracingTimeout(tsid);
52286       },
52287       tracing_session->data_source_stop_timeout_ms());
52288 
52289   // Deliberately NOT removing the session from |tracing_session_|, it's still
52290   // needed to call ReadBuffers(). FreeBuffers() will erase() the session.
52291 }
52292 
NotifyDataSourceStarted(ProducerID producer_id,DataSourceInstanceID instance_id)52293 void TracingServiceImpl::NotifyDataSourceStarted(
52294     ProducerID producer_id,
52295     DataSourceInstanceID instance_id) {
52296   PERFETTO_DCHECK_THREAD(thread_checker_);
52297   for (auto& kv : tracing_sessions_) {
52298     TracingSession& tracing_session = kv.second;
52299     DataSourceInstance* instance =
52300         tracing_session.GetDataSourceInstance(producer_id, instance_id);
52301 
52302     if (!instance)
52303       continue;
52304 
52305     // If the tracing session was already stopped, ignore this notification.
52306     if (tracing_session.state != TracingSession::STARTED)
52307       continue;
52308 
52309     if (instance->state != DataSourceInstance::STARTING) {
52310       PERFETTO_ELOG("Started data source instance in incorrect state: %d",
52311                     instance->state);
52312       continue;
52313     }
52314 
52315     instance->state = DataSourceInstance::STARTED;
52316 
52317     ProducerEndpointImpl* producer = GetProducer(producer_id);
52318     PERFETTO_DCHECK(producer);
52319     if (tracing_session.consumer_maybe_null) {
52320       tracing_session.consumer_maybe_null->OnDataSourceInstanceStateChange(
52321           *producer, *instance);
52322     }
52323 
52324     // If all data sources are started, notify the consumer.
52325     MaybeNotifyAllDataSourcesStarted(&tracing_session);
52326   }  // for (tracing_session)
52327 }
52328 
MaybeNotifyAllDataSourcesStarted(TracingSession * tracing_session)52329 void TracingServiceImpl::MaybeNotifyAllDataSourcesStarted(
52330     TracingSession* tracing_session) {
52331   if (!tracing_session->consumer_maybe_null)
52332     return;
52333 
52334   if (!tracing_session->AllDataSourceInstancesStarted())
52335     return;
52336 
52337   // In some rare cases, we can get in this state more than once. Consider the
52338   // following scenario: 3 data sources are registered -> trace starts ->
52339   // all 3 data sources ack -> OnAllDataSourcesStarted() is called.
52340   // Imagine now that a 4th data source registers while the trace is ongoing.
52341   // This would hit the AllDataSourceInstancesStarted() condition again.
52342   // In this case, however, we don't want to re-notify the consumer again.
52343   // That would be unexpected (even if, perhaps, technically correct) and
52344   // trigger bugs in the consumer.
52345   if (tracing_session->did_notify_all_data_source_started)
52346     return;
52347 
52348   PERFETTO_DLOG("All data sources started");
52349 
52350   SnapshotLifecyleEvent(
52351       tracing_session,
52352       protos::pbzero::TracingServiceEvent::kAllDataSourcesStartedFieldNumber,
52353       true /* snapshot_clocks */);
52354 
52355   tracing_session->did_notify_all_data_source_started = true;
52356   tracing_session->consumer_maybe_null->OnAllDataSourcesStarted();
52357 }
52358 
NotifyDataSourceStopped(ProducerID producer_id,DataSourceInstanceID instance_id)52359 void TracingServiceImpl::NotifyDataSourceStopped(
52360     ProducerID producer_id,
52361     DataSourceInstanceID instance_id) {
52362   PERFETTO_DCHECK_THREAD(thread_checker_);
52363   for (auto& kv : tracing_sessions_) {
52364     TracingSession& tracing_session = kv.second;
52365     DataSourceInstance* instance =
52366         tracing_session.GetDataSourceInstance(producer_id, instance_id);
52367 
52368     if (!instance)
52369       continue;
52370 
52371     if (instance->state != DataSourceInstance::STOPPING) {
52372       PERFETTO_ELOG("Stopped data source instance in incorrect state: %d",
52373                     instance->state);
52374       continue;
52375     }
52376 
52377     instance->state = DataSourceInstance::STOPPED;
52378 
52379     ProducerEndpointImpl* producer = GetProducer(producer_id);
52380     PERFETTO_DCHECK(producer);
52381     if (tracing_session.consumer_maybe_null) {
52382       tracing_session.consumer_maybe_null->OnDataSourceInstanceStateChange(
52383           *producer, *instance);
52384     }
52385 
52386     if (!tracing_session.AllDataSourceInstancesStopped())
52387       continue;
52388 
52389     if (tracing_session.state != TracingSession::DISABLING_WAITING_STOP_ACKS)
52390       continue;
52391 
52392     // All data sources acked the termination.
52393     DisableTracingNotifyConsumerAndFlushFile(&tracing_session);
52394   }  // for (tracing_session)
52395 }
52396 
ActivateTriggers(ProducerID producer_id,const std::vector<std::string> & triggers)52397 void TracingServiceImpl::ActivateTriggers(
52398     ProducerID producer_id,
52399     const std::vector<std::string>& triggers) {
52400   PERFETTO_DCHECK_THREAD(thread_checker_);
52401   auto* producer = GetProducer(producer_id);
52402   PERFETTO_DCHECK(producer);
52403 
52404   int64_t now_ns = base::GetBootTimeNs().count();
52405   for (const auto& trigger_name : triggers) {
52406     PERFETTO_DLOG("Received ActivateTriggers request for \"%s\"",
52407                   trigger_name.c_str());
52408     base::Hash hash;
52409     hash.Update(trigger_name.c_str(), trigger_name.size());
52410 
52411     uint64_t trigger_name_hash = hash.digest();
52412     size_t count_in_window =
52413         PurgeExpiredAndCountTriggerInWindow(now_ns, trigger_name_hash);
52414 
52415     bool trigger_applied = false;
52416     for (auto& id_and_tracing_session : tracing_sessions_) {
52417       auto& tracing_session = id_and_tracing_session.second;
52418       TracingSessionID tsid = id_and_tracing_session.first;
52419       auto iter = std::find_if(
52420           tracing_session.config.trigger_config().triggers().begin(),
52421           tracing_session.config.trigger_config().triggers().end(),
52422           [&trigger_name](const TraceConfig::TriggerConfig::Trigger& trigger) {
52423             return trigger.name() == trigger_name;
52424           });
52425       if (iter == tracing_session.config.trigger_config().triggers().end()) {
52426         continue;
52427       }
52428 
52429       // If this trigger requires a certain producer to have sent it
52430       // (non-empty producer_name()) ensure the producer who sent this trigger
52431       // matches.
52432       if (!iter->producer_name_regex().empty() &&
52433           !std::regex_match(
52434               producer->name_,
52435               std::regex(iter->producer_name_regex(), std::regex::extended))) {
52436         continue;
52437       }
52438 
52439       // Use a random number between 0 and 1 to check if we should allow this
52440       // trigger through or not.
52441       double trigger_rnd =
52442           trigger_rnd_override_for_testing_ > 0
52443               ? trigger_rnd_override_for_testing_
52444               : trigger_probability_dist_(trigger_probability_rand_);
52445       PERFETTO_DCHECK(trigger_rnd >= 0 && trigger_rnd < 1);
52446       if (trigger_rnd < iter->skip_probability()) {
52447         MaybeLogTriggerEvent(tracing_session.config,
52448                              PerfettoTriggerAtom::kTracedLimitProbability,
52449                              trigger_name);
52450         continue;
52451       }
52452 
52453       // If we already triggered more times than the limit, silently ignore
52454       // this trigger.
52455       if (iter->max_per_24_h() > 0 && count_in_window >= iter->max_per_24_h()) {
52456         MaybeLogTriggerEvent(tracing_session.config,
52457                              PerfettoTriggerAtom::kTracedLimitMaxPer24h,
52458                              trigger_name);
52459         continue;
52460       }
52461       trigger_applied = true;
52462 
52463       const bool triggers_already_received =
52464           !tracing_session.received_triggers.empty();
52465       tracing_session.received_triggers.push_back(
52466           {static_cast<uint64_t>(now_ns), iter->name(), producer->name_,
52467            producer->uid_});
52468       auto weak_this = weak_ptr_factory_.GetWeakPtr();
52469       switch (tracing_session.config.trigger_config().trigger_mode()) {
52470         case TraceConfig::TriggerConfig::START_TRACING:
52471           // If the session has already been triggered and moved past
52472           // CONFIGURED then we don't need to repeat StartTracing. This would
52473           // work fine (StartTracing would return false) but would add error
52474           // logs.
52475           if (tracing_session.state != TracingSession::CONFIGURED)
52476             break;
52477 
52478           PERFETTO_DLOG("Triggering '%s' on tracing session %" PRIu64
52479                         " with duration of %" PRIu32 "ms.",
52480                         iter->name().c_str(), tsid, iter->stop_delay_ms());
52481           MaybeLogUploadEvent(tracing_session.config,
52482                               PerfettoStatsdAtom::kTracedTriggerStartTracing,
52483                               iter->name());
52484 
52485           // We override the trace duration to be the trigger's requested
52486           // value, this ensures that the trace will end after this amount
52487           // of time has passed.
52488           tracing_session.config.set_duration_ms(iter->stop_delay_ms());
52489           StartTracing(tsid);
52490           break;
52491         case TraceConfig::TriggerConfig::STOP_TRACING:
52492           // Only stop the trace once to avoid confusing log messages. I.E.
52493           // when we've already hit the first trigger we've already Posted the
52494           // task to FlushAndDisable. So all future triggers will just break
52495           // out.
52496           if (triggers_already_received)
52497             break;
52498 
52499           PERFETTO_DLOG("Triggering '%s' on tracing session %" PRIu64
52500                         " with duration of %" PRIu32 "ms.",
52501                         iter->name().c_str(), tsid, iter->stop_delay_ms());
52502           MaybeLogUploadEvent(tracing_session.config,
52503                               PerfettoStatsdAtom::kTracedTriggerStopTracing,
52504                               iter->name());
52505 
52506           // Now that we've seen a trigger we need to stop, flush, and disable
52507           // this session after the configured |stop_delay_ms|.
52508           task_runner_->PostDelayedTask(
52509               [weak_this, tsid] {
52510                 // Skip entirely the flush if the trace session doesn't exist
52511                 // anymore. This is to prevent misleading error messages to be
52512                 // logged.
52513                 if (weak_this && weak_this->GetTracingSession(tsid))
52514                   weak_this->FlushAndDisableTracing(tsid);
52515               },
52516               // If this trigger is zero this will immediately executable and
52517               // will happen shortly.
52518               iter->stop_delay_ms());
52519           break;
52520         case TraceConfig::TriggerConfig::UNSPECIFIED:
52521           PERFETTO_ELOG("Trigger activated but trigger mode unspecified.");
52522           break;
52523       }
52524     }  // for (.. : tracing_sessions_)
52525 
52526     if (trigger_applied) {
52527       trigger_history_.emplace_back(TriggerHistory{now_ns, trigger_name_hash});
52528     }
52529   }
52530 }
52531 
52532 // Always invoked kDataSourceStopTimeoutMs after DisableTracing(). In nominal
52533 // conditions all data sources should have acked the stop and this will early
52534 // out.
OnDisableTracingTimeout(TracingSessionID tsid)52535 void TracingServiceImpl::OnDisableTracingTimeout(TracingSessionID tsid) {
52536   PERFETTO_DCHECK_THREAD(thread_checker_);
52537   TracingSession* tracing_session = GetTracingSession(tsid);
52538   if (!tracing_session ||
52539       tracing_session->state != TracingSession::DISABLING_WAITING_STOP_ACKS) {
52540     return;  // Tracing session was successfully disabled.
52541   }
52542 
52543   PERFETTO_ILOG("Timeout while waiting for ACKs for tracing session %" PRIu64,
52544                 tsid);
52545   PERFETTO_DCHECK(!tracing_session->AllDataSourceInstancesStopped());
52546   DisableTracingNotifyConsumerAndFlushFile(tracing_session);
52547 }
52548 
DisableTracingNotifyConsumerAndFlushFile(TracingSession * tracing_session)52549 void TracingServiceImpl::DisableTracingNotifyConsumerAndFlushFile(
52550     TracingSession* tracing_session) {
52551   PERFETTO_DCHECK(tracing_session->state != TracingSession::DISABLED);
52552   for (auto& inst_kv : tracing_session->data_source_instances) {
52553     if (inst_kv.second.state == DataSourceInstance::STOPPED)
52554       continue;
52555     inst_kv.second.state = DataSourceInstance::STOPPED;
52556     ProducerEndpointImpl* producer = GetProducer(inst_kv.first);
52557     PERFETTO_DCHECK(producer);
52558     if (tracing_session->consumer_maybe_null) {
52559       tracing_session->consumer_maybe_null->OnDataSourceInstanceStateChange(
52560           *producer, inst_kv.second);
52561     }
52562   }
52563   tracing_session->state = TracingSession::DISABLED;
52564 
52565   // Scrape any remaining chunks that weren't flushed by the producers.
52566   for (auto& producer_id_and_producer : producers_)
52567     ScrapeSharedMemoryBuffers(tracing_session, producer_id_and_producer.second);
52568 
52569   SnapshotLifecyleEvent(
52570       tracing_session,
52571       protos::pbzero::TracingServiceEvent::kTracingDisabledFieldNumber,
52572       true /* snapshot_clocks */);
52573 
52574   if (tracing_session->write_into_file) {
52575     tracing_session->write_period_ms = 0;
52576     ReadBuffers(tracing_session->id, nullptr);
52577   }
52578 
52579   if (tracing_session->on_disable_callback_for_bugreport) {
52580     std::move(tracing_session->on_disable_callback_for_bugreport)();
52581     tracing_session->on_disable_callback_for_bugreport = nullptr;
52582   }
52583 
52584   MaybeLogUploadEvent(tracing_session->config,
52585                       PerfettoStatsdAtom::kTracedNotifyTracingDisabled);
52586 
52587   if (tracing_session->consumer_maybe_null)
52588     tracing_session->consumer_maybe_null->NotifyOnTracingDisabled("");
52589 }
52590 
Flush(TracingSessionID tsid,uint32_t timeout_ms,ConsumerEndpoint::FlushCallback callback)52591 void TracingServiceImpl::Flush(TracingSessionID tsid,
52592                                uint32_t timeout_ms,
52593                                ConsumerEndpoint::FlushCallback callback) {
52594   PERFETTO_DCHECK_THREAD(thread_checker_);
52595   TracingSession* tracing_session = GetTracingSession(tsid);
52596   if (!tracing_session) {
52597     PERFETTO_DLOG("Flush() failed, invalid session ID %" PRIu64, tsid);
52598     return;
52599   }
52600 
52601   if (!timeout_ms)
52602     timeout_ms = tracing_session->flush_timeout_ms();
52603 
52604   if (tracing_session->pending_flushes.size() > 1000) {
52605     PERFETTO_ELOG("Too many flushes (%zu) pending for the tracing session",
52606                   tracing_session->pending_flushes.size());
52607     callback(false);
52608     return;
52609   }
52610 
52611   FlushRequestID flush_request_id = ++last_flush_request_id_;
52612   PendingFlush& pending_flush =
52613       tracing_session->pending_flushes
52614           .emplace_hint(tracing_session->pending_flushes.end(),
52615                         flush_request_id, PendingFlush(std::move(callback)))
52616           ->second;
52617 
52618   // Send a flush request to each producer involved in the tracing session. In
52619   // order to issue a flush request we have to build a map of all data source
52620   // instance ids enabled for each producer.
52621   std::map<ProducerID, std::vector<DataSourceInstanceID>> flush_map;
52622   for (const auto& data_source_inst : tracing_session->data_source_instances) {
52623     const ProducerID producer_id = data_source_inst.first;
52624     const DataSourceInstanceID ds_inst_id = data_source_inst.second.instance_id;
52625     flush_map[producer_id].push_back(ds_inst_id);
52626   }
52627 
52628   for (const auto& kv : flush_map) {
52629     ProducerID producer_id = kv.first;
52630     ProducerEndpointImpl* producer = GetProducer(producer_id);
52631     const std::vector<DataSourceInstanceID>& data_sources = kv.second;
52632     producer->Flush(flush_request_id, data_sources);
52633     pending_flush.producers.insert(producer_id);
52634   }
52635 
52636   // If there are no producers to flush (realistically this happens only in
52637   // some tests) fire OnFlushTimeout() straight away, without waiting.
52638   if (flush_map.empty())
52639     timeout_ms = 0;
52640 
52641   auto weak_this = weak_ptr_factory_.GetWeakPtr();
52642   task_runner_->PostDelayedTask(
52643       [weak_this, tsid, flush_request_id] {
52644         if (weak_this)
52645           weak_this->OnFlushTimeout(tsid, flush_request_id);
52646       },
52647       timeout_ms);
52648 }
52649 
NotifyFlushDoneForProducer(ProducerID producer_id,FlushRequestID flush_request_id)52650 void TracingServiceImpl::NotifyFlushDoneForProducer(
52651     ProducerID producer_id,
52652     FlushRequestID flush_request_id) {
52653   for (auto& kv : tracing_sessions_) {
52654     // Remove all pending flushes <= |flush_request_id| for |producer_id|.
52655     auto& pending_flushes = kv.second.pending_flushes;
52656     auto end_it = pending_flushes.upper_bound(flush_request_id);
52657     for (auto it = pending_flushes.begin(); it != end_it;) {
52658       PendingFlush& pending_flush = it->second;
52659       pending_flush.producers.erase(producer_id);
52660       if (pending_flush.producers.empty()) {
52661         auto weak_this = weak_ptr_factory_.GetWeakPtr();
52662         TracingSessionID tsid = kv.first;
52663         auto callback = std::move(pending_flush.callback);
52664         task_runner_->PostTask([weak_this, tsid, callback]() {
52665           if (weak_this) {
52666             weak_this->CompleteFlush(tsid, std::move(callback),
52667                                      /*success=*/true);
52668           }
52669         });
52670         it = pending_flushes.erase(it);
52671       } else {
52672         it++;
52673       }
52674     }  // for (pending_flushes)
52675   }    // for (tracing_session)
52676 }
52677 
OnFlushTimeout(TracingSessionID tsid,FlushRequestID flush_request_id)52678 void TracingServiceImpl::OnFlushTimeout(TracingSessionID tsid,
52679                                         FlushRequestID flush_request_id) {
52680   TracingSession* tracing_session = GetTracingSession(tsid);
52681   if (!tracing_session)
52682     return;
52683   auto it = tracing_session->pending_flushes.find(flush_request_id);
52684   if (it == tracing_session->pending_flushes.end())
52685     return;  // Nominal case: flush was completed and acked on time.
52686 
52687   // If there were no producers to flush, consider it a success.
52688   bool success = it->second.producers.empty();
52689 
52690   auto callback = std::move(it->second.callback);
52691   tracing_session->pending_flushes.erase(it);
52692   CompleteFlush(tsid, std::move(callback), success);
52693 }
52694 
CompleteFlush(TracingSessionID tsid,ConsumerEndpoint::FlushCallback callback,bool success)52695 void TracingServiceImpl::CompleteFlush(TracingSessionID tsid,
52696                                        ConsumerEndpoint::FlushCallback callback,
52697                                        bool success) {
52698   TracingSession* tracing_session = GetTracingSession(tsid);
52699   if (!tracing_session) {
52700     callback(false);
52701     return;
52702   }
52703   // Producers may not have been able to flush all their data, even if they
52704   // indicated flush completion. If possible, also collect uncommitted chunks
52705   // to make sure we have everything they wrote so far.
52706   for (auto& producer_id_and_producer : producers_) {
52707     ScrapeSharedMemoryBuffers(tracing_session, producer_id_and_producer.second);
52708   }
52709   SnapshotLifecyleEvent(
52710       tracing_session,
52711       protos::pbzero::TracingServiceEvent::kAllDataSourcesFlushedFieldNumber,
52712       true /* snapshot_clocks */);
52713   callback(success);
52714 }
52715 
ScrapeSharedMemoryBuffers(TracingSession * tracing_session,ProducerEndpointImpl * producer)52716 void TracingServiceImpl::ScrapeSharedMemoryBuffers(
52717     TracingSession* tracing_session,
52718     ProducerEndpointImpl* producer) {
52719   if (!producer->smb_scraping_enabled_)
52720     return;
52721 
52722   // Can't copy chunks if we don't know about any trace writers.
52723   if (producer->writers_.empty())
52724     return;
52725 
52726   // Performance optimization: On flush or session disconnect, this method is
52727   // called for each producer. If the producer doesn't participate in the
52728   // session, there's no need to scape its chunks right now. We can tell if a
52729   // producer participates in the session by checking if the producer is allowed
52730   // to write into the session's log buffers.
52731   const auto& session_buffers = tracing_session->buffers_index;
52732   bool producer_in_session =
52733       std::any_of(session_buffers.begin(), session_buffers.end(),
52734                   [producer](BufferID buffer_id) {
52735                     return producer->allowed_target_buffers_.count(buffer_id);
52736                   });
52737   if (!producer_in_session)
52738     return;
52739 
52740   PERFETTO_DLOG("Scraping SMB for producer %" PRIu16, producer->id_);
52741 
52742   // Find and copy any uncommitted chunks from the SMB.
52743   //
52744   // In nominal conditions, the page layout of the used SMB pages should never
52745   // change because the service is the only one who is supposed to modify used
52746   // pages (to make them free again).
52747   //
52748   // However, the code here needs to deal with the case of a malicious producer
52749   // altering the SMB in unpredictable ways. Thankfully the SMB size is
52750   // immutable, so a chunk will always point to some valid memory, even if the
52751   // producer alters the intended layout and chunk header concurrently.
52752   // Ultimately a malicious producer altering the SMB's chunk layout while we
52753   // are iterating in this function is not any different from the case of a
52754   // malicious producer asking to commit a chunk made of random data, which is
52755   // something this class has to deal with regardless.
52756   //
52757   // The only legitimate mutations that can happen from sane producers,
52758   // concurrently to this function, are:
52759   //   A. free pages being partitioned,
52760   //   B. free chunks being migrated to kChunkBeingWritten,
52761   //   C. kChunkBeingWritten chunks being migrated to kChunkCompleted.
52762 
52763   SharedMemoryABI* abi = &producer->shmem_abi_;
52764   // num_pages() is immutable after the SMB is initialized and cannot be changed
52765   // even by a producer even if malicious.
52766   for (size_t page_idx = 0; page_idx < abi->num_pages(); page_idx++) {
52767     uint32_t layout = abi->GetPageLayout(page_idx);
52768 
52769     uint32_t used_chunks = abi->GetUsedChunks(layout);  // Returns a bitmap.
52770     // Skip empty pages.
52771     if (used_chunks == 0)
52772       continue;
52773 
52774     // Scrape the chunks that are currently used. These should be either in
52775     // state kChunkBeingWritten or kChunkComplete.
52776     for (uint32_t chunk_idx = 0; used_chunks; chunk_idx++, used_chunks >>= 1) {
52777       if (!(used_chunks & 1))
52778         continue;
52779 
52780       SharedMemoryABI::ChunkState state =
52781           SharedMemoryABI::GetChunkStateFromLayout(layout, chunk_idx);
52782       PERFETTO_DCHECK(state == SharedMemoryABI::kChunkBeingWritten ||
52783                       state == SharedMemoryABI::kChunkComplete);
52784       bool chunk_complete = state == SharedMemoryABI::kChunkComplete;
52785 
52786       SharedMemoryABI::Chunk chunk =
52787           abi->GetChunkUnchecked(page_idx, layout, chunk_idx);
52788 
52789       uint16_t packet_count;
52790       uint8_t flags;
52791       // GetPacketCountAndFlags has acquire_load semantics.
52792       std::tie(packet_count, flags) = chunk.GetPacketCountAndFlags();
52793 
52794       // It only makes sense to copy an incomplete chunk if there's at least
52795       // one full packet available. (The producer may not have completed the
52796       // last packet in it yet, so we need at least 2.)
52797       if (!chunk_complete && packet_count < 2)
52798         continue;
52799 
52800       // At this point, it is safe to access the remaining header fields of
52801       // the chunk. Even if the chunk was only just transferred from
52802       // kChunkFree into kChunkBeingWritten state, the header should be
52803       // written completely once the packet count increased above 1 (it was
52804       // reset to 0 by the service when the chunk was freed).
52805 
52806       WriterID writer_id = chunk.writer_id();
52807       base::Optional<BufferID> target_buffer_id =
52808           producer->buffer_id_for_writer(writer_id);
52809 
52810       // We can only scrape this chunk if we know which log buffer to copy it
52811       // into.
52812       if (!target_buffer_id)
52813         continue;
52814 
52815       // Skip chunks that don't belong to the requested tracing session.
52816       bool target_buffer_belongs_to_session =
52817           std::find(session_buffers.begin(), session_buffers.end(),
52818                     *target_buffer_id) != session_buffers.end();
52819       if (!target_buffer_belongs_to_session)
52820         continue;
52821 
52822       uint32_t chunk_id =
52823           chunk.header()->chunk_id.load(std::memory_order_relaxed);
52824 
52825       CopyProducerPageIntoLogBuffer(
52826           producer->id_, producer->uid_, writer_id, chunk_id, *target_buffer_id,
52827           packet_count, flags, chunk_complete, chunk.payload_begin(),
52828           chunk.payload_size());
52829     }
52830   }
52831 }
52832 
FlushAndDisableTracing(TracingSessionID tsid)52833 void TracingServiceImpl::FlushAndDisableTracing(TracingSessionID tsid) {
52834   PERFETTO_DCHECK_THREAD(thread_checker_);
52835   PERFETTO_DLOG("Triggering final flush for %" PRIu64, tsid);
52836   auto weak_this = weak_ptr_factory_.GetWeakPtr();
52837   Flush(tsid, 0, [weak_this, tsid](bool success) {
52838     // This was a DLOG up to Jun 2021 (v16, Android S).
52839     PERFETTO_LOG("FlushAndDisableTracing(%" PRIu64 ") done, success=%d", tsid,
52840                  success);
52841     if (!weak_this)
52842       return;
52843     TracingSession* session = weak_this->GetTracingSession(tsid);
52844     if (session->consumer_maybe_null) {
52845       // If the consumer is still attached, just disable the session but give it
52846       // a chance to read the contents.
52847       weak_this->DisableTracing(tsid);
52848     } else {
52849       // If the consumer detached, destroy the session. If the consumer did
52850       // start the session in long-tracing mode, the service will have saved
52851       // the contents to the passed file. If not, the contents will be
52852       // destroyed.
52853       weak_this->FreeBuffers(tsid);
52854     }
52855   });
52856 }
52857 
PeriodicFlushTask(TracingSessionID tsid,bool post_next_only)52858 void TracingServiceImpl::PeriodicFlushTask(TracingSessionID tsid,
52859                                            bool post_next_only) {
52860   PERFETTO_DCHECK_THREAD(thread_checker_);
52861   TracingSession* tracing_session = GetTracingSession(tsid);
52862   if (!tracing_session || tracing_session->state != TracingSession::STARTED)
52863     return;
52864 
52865   uint32_t flush_period_ms = tracing_session->config.flush_period_ms();
52866   auto weak_this = weak_ptr_factory_.GetWeakPtr();
52867   task_runner_->PostDelayedTask(
52868       [weak_this, tsid] {
52869         if (weak_this)
52870           weak_this->PeriodicFlushTask(tsid, /*post_next_only=*/false);
52871       },
52872       flush_period_ms - static_cast<uint32_t>(base::GetWallTimeMs().count() %
52873                                               flush_period_ms));
52874 
52875   if (post_next_only)
52876     return;
52877 
52878   PERFETTO_DLOG("Triggering periodic flush for trace session %" PRIu64, tsid);
52879   Flush(tsid, 0, [](bool success) {
52880     if (!success)
52881       PERFETTO_ELOG("Periodic flush timed out");
52882   });
52883 }
52884 
PeriodicClearIncrementalStateTask(TracingSessionID tsid,bool post_next_only)52885 void TracingServiceImpl::PeriodicClearIncrementalStateTask(
52886     TracingSessionID tsid,
52887     bool post_next_only) {
52888   PERFETTO_DCHECK_THREAD(thread_checker_);
52889   TracingSession* tracing_session = GetTracingSession(tsid);
52890   if (!tracing_session || tracing_session->state != TracingSession::STARTED)
52891     return;
52892 
52893   uint32_t clear_period_ms =
52894       tracing_session->config.incremental_state_config().clear_period_ms();
52895   auto weak_this = weak_ptr_factory_.GetWeakPtr();
52896   task_runner_->PostDelayedTask(
52897       [weak_this, tsid] {
52898         if (weak_this)
52899           weak_this->PeriodicClearIncrementalStateTask(
52900               tsid, /*post_next_only=*/false);
52901       },
52902       clear_period_ms - static_cast<uint32_t>(base::GetWallTimeMs().count() %
52903                                               clear_period_ms));
52904 
52905   if (post_next_only)
52906     return;
52907 
52908   PERFETTO_DLOG(
52909       "Performing periodic incremental state clear for trace session %" PRIu64,
52910       tsid);
52911 
52912   // Queue the IPCs to producers with active data sources that opted in.
52913   std::map<ProducerID, std::vector<DataSourceInstanceID>> clear_map;
52914   for (const auto& kv : tracing_session->data_source_instances) {
52915     ProducerID producer_id = kv.first;
52916     const DataSourceInstance& data_source = kv.second;
52917     if (data_source.handles_incremental_state_clear)
52918       clear_map[producer_id].push_back(data_source.instance_id);
52919   }
52920 
52921   for (const auto& kv : clear_map) {
52922     ProducerID producer_id = kv.first;
52923     const std::vector<DataSourceInstanceID>& data_sources = kv.second;
52924     ProducerEndpointImpl* producer = GetProducer(producer_id);
52925     if (!producer) {
52926       PERFETTO_DFATAL("Producer does not exist.");
52927       continue;
52928     }
52929     producer->ClearIncrementalState(data_sources);
52930   }
52931 }
52932 
52933 // Note: when this is called to write into a file passed when starting tracing
52934 // |consumer| will be == nullptr (as opposite to the case of a consumer asking
52935 // to send the trace data back over IPC).
ReadBuffers(TracingSessionID tsid,ConsumerEndpointImpl * consumer)52936 bool TracingServiceImpl::ReadBuffers(TracingSessionID tsid,
52937                                      ConsumerEndpointImpl* consumer) {
52938   PERFETTO_DCHECK_THREAD(thread_checker_);
52939   TracingSession* tracing_session = GetTracingSession(tsid);
52940   if (!tracing_session) {
52941     // This will be hit systematically from the PostDelayedTask when directly
52942     // writing into the file (in which case consumer == nullptr). Suppress the
52943     // log in this case as it's just spam.
52944     if (consumer) {
52945       PERFETTO_DLOG("Cannot ReadBuffers(): no tracing session is active");
52946     }
52947     return false;
52948   }
52949 
52950   // When a tracing session is waiting for a trigger it is considered empty. If
52951   // a tracing session finishes and moves into DISABLED without ever receiving a
52952   // trigger the trace should never return any data. This includes the synthetic
52953   // packets like TraceConfig and Clock snapshots. So we bail out early and let
52954   // the consumer know there is no data.
52955   if (!tracing_session->config.trigger_config().triggers().empty() &&
52956       tracing_session->received_triggers.empty() &&
52957       !tracing_session->seized_for_bugreport) {
52958     PERFETTO_DLOG(
52959         "ReadBuffers(): tracing session has not received a trigger yet.");
52960     return false;
52961   }
52962 
52963   // This can happen if the file is closed by a previous task because it reaches
52964   // |max_file_size_bytes|.
52965   if (!tracing_session->write_into_file && !consumer)
52966     return false;
52967 
52968   if (tracing_session->write_into_file && consumer) {
52969     // If the consumer enabled tracing and asked to save the contents into the
52970     // passed file makes little sense to also try to read the buffers over IPC,
52971     // as that would just steal data from the periodic draining task.
52972     PERFETTO_ELOG("Consumer trying to read from write_into_file session.");
52973     return false;
52974   }
52975 
52976   std::vector<TracePacket> packets;
52977   packets.reserve(1024);  // Just an educated guess to avoid trivial expansions.
52978 
52979   // If a bugreport request happened and the trace was stolen for that, give
52980   // an empty trace with a clear signal to the consumer. This deals only with
52981   // the case of readback-from-IPC. A similar code-path deals with the
52982   // write_into_file case in MaybeSaveTraceForBugreport().
52983   if (tracing_session->seized_for_bugreport && consumer) {
52984     if (!tracing_session->config.builtin_data_sources()
52985              .disable_service_events()) {
52986       EmitSeizedForBugreportLifecycleEvent(&packets);
52987     }
52988     EmitLifecycleEvents(tracing_session, &packets);
52989     consumer->consumer_->OnTraceData(std::move(packets), /*has_more=*/false);
52990     return true;
52991   }
52992 
52993   if (!tracing_session->initial_clock_snapshot.empty()) {
52994     EmitClockSnapshot(tracing_session,
52995                       std::move(tracing_session->initial_clock_snapshot),
52996                       &packets);
52997   }
52998 
52999   for (auto& snapshot : tracing_session->clock_snapshot_ring_buffer) {
53000     PERFETTO_DCHECK(!snapshot.empty());
53001     EmitClockSnapshot(tracing_session, std::move(snapshot), &packets);
53002   }
53003   tracing_session->clock_snapshot_ring_buffer.clear();
53004 
53005   if (tracing_session->should_emit_sync_marker) {
53006     EmitSyncMarker(&packets);
53007     tracing_session->should_emit_sync_marker = false;
53008   }
53009 
53010   if (!tracing_session->config.builtin_data_sources().disable_trace_config()) {
53011     MaybeEmitTraceConfig(tracing_session, &packets);
53012     MaybeEmitReceivedTriggers(tracing_session, &packets);
53013   }
53014   if (!tracing_session->config.builtin_data_sources().disable_system_info())
53015     MaybeEmitSystemInfo(tracing_session, &packets);
53016 
53017   // Note that in the proto comment, we guarantee that the tracing_started
53018   // lifecycle event will be emitted before any data packets so make sure to
53019   // keep this before reading the tracing buffers.
53020   if (!tracing_session->config.builtin_data_sources().disable_service_events())
53021     EmitLifecycleEvents(tracing_session, &packets);
53022 
53023   size_t packets_bytes = 0;  // SUM(slice.size() for each slice in |packets|).
53024   size_t total_slices = 0;   // SUM(#slices in |packets|).
53025 
53026   // Add up size for packets added by the Maybe* calls above.
53027   for (const TracePacket& packet : packets) {
53028     packets_bytes += packet.size();
53029     total_slices += packet.slices().size();
53030   }
53031 
53032   // This is a rough threshold to determine how much to read from the buffer in
53033   // each task. This is to avoid executing a single huge sending task for too
53034   // long and risk to hit the watchdog. This is *not* an upper bound: we just
53035   // stop accumulating new packets and PostTask *after* we cross this threshold.
53036   // This constant essentially balances the PostTask and IPC overhead vs the
53037   // responsiveness of the service. An extremely small value will cause one IPC
53038   // and one PostTask for each slice but will keep the service extremely
53039   // responsive. An extremely large value will batch the send for the full
53040   // buffer in one large task, will hit the blocking send() once the socket
53041   // buffers are full and hang the service for a bit (until the consumer
53042   // catches up).
53043   static constexpr size_t kApproxBytesPerTask = 32768;
53044   bool did_hit_threshold = false;
53045 
53046   // TODO(primiano): Extend the ReadBuffers API to allow reading only some
53047   // buffers, not all of them in one go.
53048   for (size_t buf_idx = 0;
53049        buf_idx < tracing_session->num_buffers() && !did_hit_threshold;
53050        buf_idx++) {
53051     auto tbuf_iter = buffers_.find(tracing_session->buffers_index[buf_idx]);
53052     if (tbuf_iter == buffers_.end()) {
53053       PERFETTO_DFATAL("Buffer not found.");
53054       continue;
53055     }
53056     TraceBuffer& tbuf = *tbuf_iter->second;
53057     tbuf.BeginRead();
53058     while (!did_hit_threshold) {
53059       TracePacket packet;
53060       TraceBuffer::PacketSequenceProperties sequence_properties{};
53061       bool previous_packet_dropped;
53062       if (!tbuf.ReadNextTracePacket(&packet, &sequence_properties,
53063                                     &previous_packet_dropped)) {
53064         break;
53065       }
53066       PERFETTO_DCHECK(sequence_properties.producer_id_trusted != 0);
53067       PERFETTO_DCHECK(sequence_properties.writer_id != 0);
53068       PERFETTO_DCHECK(sequence_properties.producer_uid_trusted != kInvalidUid);
53069       PERFETTO_DCHECK(packet.size() > 0);
53070       if (!PacketStreamValidator::Validate(packet.slices())) {
53071         tracing_session->invalid_packets++;
53072         PERFETTO_DLOG("Dropping invalid packet");
53073         continue;
53074       }
53075 
53076       // Append a slice with the trusted field data. This can't be spoofed
53077       // because above we validated that the existing slices don't contain any
53078       // trusted fields. For added safety we append instead of prepending
53079       // because according to protobuf semantics, if the same field is
53080       // encountered multiple times the last instance takes priority. Note that
53081       // truncated packets are also rejected, so the producer can't give us a
53082       // partial packet (e.g., a truncated string) which only becomes valid when
53083       // the trusted data is appended here.
53084       Slice slice = Slice::Allocate(32);
53085       protozero::StaticBuffered<protos::pbzero::TracePacket> trusted_packet(
53086           slice.own_data(), slice.size);
53087       trusted_packet->set_trusted_uid(
53088           static_cast<int32_t>(sequence_properties.producer_uid_trusted));
53089       trusted_packet->set_trusted_packet_sequence_id(
53090           tracing_session->GetPacketSequenceID(
53091               sequence_properties.producer_id_trusted,
53092               sequence_properties.writer_id));
53093       if (previous_packet_dropped)
53094         trusted_packet->set_previous_packet_dropped(previous_packet_dropped);
53095       slice.size = trusted_packet.Finalize();
53096       packet.AddSlice(std::move(slice));
53097 
53098       // Append the packet (inclusive of the trusted uid) to |packets|.
53099       packets_bytes += packet.size();
53100       total_slices += packet.slices().size();
53101       did_hit_threshold = packets_bytes >= kApproxBytesPerTask &&
53102                           !tracing_session->write_into_file;
53103       packets.emplace_back(std::move(packet));
53104     }  // for(packets...)
53105   }    // for(buffers...)
53106 
53107   const bool has_more = did_hit_threshold;
53108 
53109   size_t prev_packets_size = packets.size();
53110   if (!tracing_session->config.builtin_data_sources()
53111            .disable_service_events()) {
53112     // We don't bother snapshotting clocks here because we wouldn't be able to
53113     // emit it and we shouldn't have significant drift from the last snapshot in
53114     // any case.
53115     SnapshotLifecyleEvent(tracing_session,
53116                           protos::pbzero::TracingServiceEvent::
53117                               kReadTracingBuffersCompletedFieldNumber,
53118                           false /* snapshot_clocks */);
53119     EmitLifecycleEvents(tracing_session, &packets);
53120   }
53121 
53122   // Only emit the stats when there is no more trace data is available to read.
53123   // That way, any problems that occur while reading from the buffers are
53124   // reflected in the emitted stats. This is particularly important for use
53125   // cases where ReadBuffers is only ever called after the tracing session is
53126   // stopped.
53127   if (!has_more && tracing_session->should_emit_stats) {
53128     EmitStats(tracing_session, &packets);
53129     tracing_session->should_emit_stats = false;
53130   }
53131 
53132   // Add sizes of packets emitted by the EmitLifecycleEvents + EmitStats.
53133   for (size_t i = prev_packets_size; i < packets.size(); ++i) {
53134     packets_bytes += packets[i].size();
53135     total_slices += packets[i].slices().size();
53136   }
53137 
53138   // +-------------------------------------------------------------------------+
53139   // | NO MORE CHANGES TO |packets| AFTER THIS POINT.                          |
53140   // +-------------------------------------------------------------------------+
53141 
53142   // If the tracing session specified a filter, run all packets through the
53143   // filter and replace them with the filter results.
53144   // The process below mantains the cardinality of input packets. Even if an
53145   // entire packet is filtered out, we emit a zero-sized TracePacket proto. That
53146   // makes debugging and reasoning about the trace stats easier.
53147   // This place swaps the contents of each |packets| entry in place.
53148   if (tracing_session->trace_filter) {
53149     auto& trace_filter = *tracing_session->trace_filter;
53150     // The filter root shoud be reset from protos.Trace to protos.TracePacket
53151     // by the earlier call to SetFilterRoot() in EnableTracing().
53152     PERFETTO_DCHECK(trace_filter.root_msg_index() != 0);
53153     std::vector<protozero::MessageFilter::InputSlice> filter_input;
53154     for (auto it = packets.begin(); it != packets.end(); ++it) {
53155       const auto& packet_slices = it->slices();
53156       filter_input.clear();
53157       filter_input.resize(packet_slices.size());
53158       ++tracing_session->filter_input_packets;
53159       tracing_session->filter_input_bytes += it->size();
53160       for (size_t i = 0; i < packet_slices.size(); ++i)
53161         filter_input[i] = {packet_slices[i].start, packet_slices[i].size};
53162       auto filtered_packet = trace_filter.FilterMessageFragments(
53163           &filter_input[0], filter_input.size());
53164 
53165       // Replace the packet in-place with the filtered one (unless failed).
53166       *it = TracePacket();
53167       if (filtered_packet.error) {
53168         ++tracing_session->filter_errors;
53169         PERFETTO_DLOG("Trace packet filtering failed @ packet %" PRIu64,
53170                       tracing_session->filter_input_packets);
53171         continue;
53172       }
53173       tracing_session->filter_output_bytes += filtered_packet.size;
53174       it->AddSlice(Slice::TakeOwnership(std::move(filtered_packet.data),
53175                                         filtered_packet.size));
53176 
53177     }  // for (packet)
53178   }    // if (trace_filter)
53179 
53180   // If the caller asked us to write into a file by setting
53181   // |write_into_file| == true in the trace config, drain the packets read
53182   // (if any) into the given file descriptor.
53183   if (tracing_session->write_into_file) {
53184     const uint64_t max_size = tracing_session->max_file_size_bytes
53185                                   ? tracing_session->max_file_size_bytes
53186                                   : std::numeric_limits<size_t>::max();
53187 
53188     // When writing into a file, the file should look like a root trace.proto
53189     // message. Each packet should be prepended with a proto preamble stating
53190     // its field id (within trace.proto) and size. Hence the addition below.
53191     const size_t max_iovecs = total_slices + packets.size();
53192 
53193     size_t num_iovecs = 0;
53194     bool stop_writing_into_file = tracing_session->write_period_ms == 0;
53195     std::unique_ptr<struct iovec[]> iovecs(new struct iovec[max_iovecs]);
53196     size_t num_iovecs_at_last_packet = 0;
53197     uint64_t bytes_about_to_be_written = 0;
53198     for (TracePacket& packet : packets) {
53199       std::tie(iovecs[num_iovecs].iov_base, iovecs[num_iovecs].iov_len) =
53200           packet.GetProtoPreamble();
53201       bytes_about_to_be_written += iovecs[num_iovecs].iov_len;
53202       num_iovecs++;
53203       for (const Slice& slice : packet.slices()) {
53204         // writev() doesn't change the passed pointer. However, struct iovec
53205         // take a non-const ptr because it's the same struct used by readv().
53206         // Hence the const_cast here.
53207         char* start = static_cast<char*>(const_cast<void*>(slice.start));
53208         bytes_about_to_be_written += slice.size;
53209         iovecs[num_iovecs++] = {start, slice.size};
53210       }
53211 
53212       if (tracing_session->bytes_written_into_file +
53213               bytes_about_to_be_written >=
53214           max_size) {
53215         stop_writing_into_file = true;
53216         num_iovecs = num_iovecs_at_last_packet;
53217         break;
53218       }
53219 
53220       num_iovecs_at_last_packet = num_iovecs;
53221     }
53222     PERFETTO_DCHECK(num_iovecs <= max_iovecs);
53223     int fd = *tracing_session->write_into_file;
53224 
53225     uint64_t total_wr_size = 0;
53226 
53227     // writev() can take at most IOV_MAX entries per call. Batch them.
53228     constexpr size_t kIOVMax = IOV_MAX;
53229     for (size_t i = 0; i < num_iovecs; i += kIOVMax) {
53230       int iov_batch_size = static_cast<int>(std::min(num_iovecs - i, kIOVMax));
53231       ssize_t wr_size = PERFETTO_EINTR(writev(fd, &iovecs[i], iov_batch_size));
53232       if (wr_size <= 0) {
53233         PERFETTO_PLOG("writev() failed");
53234         stop_writing_into_file = true;
53235         break;
53236       }
53237       total_wr_size += static_cast<size_t>(wr_size);
53238     }
53239 
53240     tracing_session->bytes_written_into_file += total_wr_size;
53241 
53242     PERFETTO_DLOG("Draining into file, written: %" PRIu64 " KB, stop: %d",
53243                   (total_wr_size + 1023) / 1024, stop_writing_into_file);
53244     if (stop_writing_into_file) {
53245       // Ensure all data was written to the file before we close it.
53246       base::FlushFile(fd);
53247       tracing_session->write_into_file.reset();
53248       tracing_session->write_period_ms = 0;
53249       if (tracing_session->state == TracingSession::STARTED)
53250         DisableTracing(tsid);
53251       return true;
53252     }
53253 
53254     auto weak_this = weak_ptr_factory_.GetWeakPtr();
53255     task_runner_->PostDelayedTask(
53256         [weak_this, tsid] {
53257           if (weak_this)
53258             weak_this->ReadBuffers(tsid, nullptr);
53259         },
53260         tracing_session->delay_to_next_write_period_ms());
53261     return true;
53262   }  // if (tracing_session->write_into_file)
53263 
53264   if (has_more) {
53265     auto weak_consumer = consumer->weak_ptr_factory_.GetWeakPtr();
53266     auto weak_this = weak_ptr_factory_.GetWeakPtr();
53267     task_runner_->PostTask([weak_this, weak_consumer, tsid] {
53268       if (!weak_this || !weak_consumer)
53269         return;
53270       weak_this->ReadBuffers(tsid, weak_consumer.get());
53271     });
53272   }
53273 
53274   // Keep this as tail call, just in case the consumer re-enters.
53275   consumer->consumer_->OnTraceData(std::move(packets), has_more);
53276   return true;
53277 }
53278 
FreeBuffers(TracingSessionID tsid)53279 void TracingServiceImpl::FreeBuffers(TracingSessionID tsid) {
53280   PERFETTO_DCHECK_THREAD(thread_checker_);
53281   PERFETTO_DLOG("Freeing buffers for session %" PRIu64, tsid);
53282   TracingSession* tracing_session = GetTracingSession(tsid);
53283   if (!tracing_session) {
53284     PERFETTO_DLOG("FreeBuffers() failed, invalid session ID %" PRIu64, tsid);
53285     return;  // TODO(primiano): signal failure?
53286   }
53287   DisableTracing(tsid, /*disable_immediately=*/true);
53288 
53289   PERFETTO_DCHECK(tracing_session->AllDataSourceInstancesStopped());
53290   tracing_session->data_source_instances.clear();
53291 
53292   for (auto& producer_entry : producers_) {
53293     ProducerEndpointImpl* producer = producer_entry.second;
53294     producer->OnFreeBuffers(tracing_session->buffers_index);
53295   }
53296 
53297   for (BufferID buffer_id : tracing_session->buffers_index) {
53298     buffer_ids_.Free(buffer_id);
53299     PERFETTO_DCHECK(buffers_.count(buffer_id) == 1);
53300     buffers_.erase(buffer_id);
53301   }
53302   bool notify_traceur = tracing_session->config.notify_traceur();
53303   bool is_long_trace =
53304       (tracing_session->config.write_into_file() &&
53305        tracing_session->config.file_write_period_ms() < kMillisPerDay);
53306   bool seized_for_bugreport = tracing_session->seized_for_bugreport;
53307   tracing_sessions_.erase(tsid);
53308   tracing_session = nullptr;
53309   UpdateMemoryGuardrail();
53310 
53311   PERFETTO_LOG("Tracing session %" PRIu64 " ended, total sessions:%zu", tsid,
53312                tracing_sessions_.size());
53313 
53314 #if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD) && \
53315     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
53316   if (notify_traceur && (seized_for_bugreport || is_long_trace)) {
53317     PERFETTO_LAZY_LOAD(android_internal::NotifyTraceSessionEnded, notify_fn);
53318     if (!notify_fn || !notify_fn(seized_for_bugreport))
53319       PERFETTO_ELOG("Failed to notify Traceur long tracing has ended");
53320   }
53321 #else
53322   base::ignore_result(notify_traceur);
53323   base::ignore_result(is_long_trace);
53324   base::ignore_result(seized_for_bugreport);
53325 #endif
53326 }
53327 
RegisterDataSource(ProducerID producer_id,const DataSourceDescriptor & desc)53328 void TracingServiceImpl::RegisterDataSource(ProducerID producer_id,
53329                                             const DataSourceDescriptor& desc) {
53330   PERFETTO_DCHECK_THREAD(thread_checker_);
53331   PERFETTO_DLOG("Producer %" PRIu16 " registered data source \"%s\"",
53332                 producer_id, desc.name().c_str());
53333 
53334   PERFETTO_DCHECK(!desc.name().empty());
53335   auto reg_ds = data_sources_.emplace(desc.name(),
53336                                       RegisteredDataSource{producer_id, desc});
53337 
53338   // If there are existing tracing sessions, we need to check if the new
53339   // data source is enabled by any of them.
53340   if (tracing_sessions_.empty())
53341     return;
53342 
53343   ProducerEndpointImpl* producer = GetProducer(producer_id);
53344   if (!producer) {
53345     PERFETTO_DFATAL("Producer not found.");
53346     return;
53347   }
53348 
53349   for (auto& iter : tracing_sessions_) {
53350     TracingSession& tracing_session = iter.second;
53351     if (tracing_session.state != TracingSession::STARTED &&
53352         tracing_session.state != TracingSession::CONFIGURED) {
53353       continue;
53354     }
53355 
53356     TraceConfig::ProducerConfig producer_config;
53357     for (auto& config : tracing_session.config.producers()) {
53358       if (producer->name_ == config.producer_name()) {
53359         producer_config = config;
53360         break;
53361       }
53362     }
53363     for (const TraceConfig::DataSource& cfg_data_source :
53364          tracing_session.config.data_sources()) {
53365       if (cfg_data_source.config().name() != desc.name())
53366         continue;
53367       DataSourceInstance* ds_inst = SetupDataSource(
53368           cfg_data_source, producer_config, reg_ds->second, &tracing_session);
53369       if (ds_inst && tracing_session.state == TracingSession::STARTED)
53370         StartDataSourceInstance(producer, &tracing_session, ds_inst);
53371     }
53372   }
53373 }
53374 
StopDataSourceInstance(ProducerEndpointImpl * producer,TracingSession * tracing_session,DataSourceInstance * instance,bool disable_immediately)53375 void TracingServiceImpl::StopDataSourceInstance(ProducerEndpointImpl* producer,
53376                                                 TracingSession* tracing_session,
53377                                                 DataSourceInstance* instance,
53378                                                 bool disable_immediately) {
53379   const DataSourceInstanceID ds_inst_id = instance->instance_id;
53380   if (instance->will_notify_on_stop && !disable_immediately) {
53381     instance->state = DataSourceInstance::STOPPING;
53382   } else {
53383     instance->state = DataSourceInstance::STOPPED;
53384   }
53385   if (tracing_session->consumer_maybe_null) {
53386     tracing_session->consumer_maybe_null->OnDataSourceInstanceStateChange(
53387         *producer, *instance);
53388   }
53389   producer->StopDataSource(ds_inst_id);
53390 }
53391 
UnregisterDataSource(ProducerID producer_id,const std::string & name)53392 void TracingServiceImpl::UnregisterDataSource(ProducerID producer_id,
53393                                               const std::string& name) {
53394   PERFETTO_DCHECK_THREAD(thread_checker_);
53395   PERFETTO_DLOG("Producer %" PRIu16 " unregistered data source \"%s\"",
53396                 producer_id, name.c_str());
53397   PERFETTO_CHECK(producer_id);
53398   ProducerEndpointImpl* producer = GetProducer(producer_id);
53399   PERFETTO_DCHECK(producer);
53400   for (auto& kv : tracing_sessions_) {
53401     auto& ds_instances = kv.second.data_source_instances;
53402     bool removed = false;
53403     for (auto it = ds_instances.begin(); it != ds_instances.end();) {
53404       if (it->first == producer_id && it->second.data_source_name == name) {
53405         DataSourceInstanceID ds_inst_id = it->second.instance_id;
53406         if (it->second.state != DataSourceInstance::STOPPED) {
53407           if (it->second.state != DataSourceInstance::STOPPING) {
53408             StopDataSourceInstance(producer, &kv.second, &it->second,
53409                                    /* disable_immediately = */ false);
53410           }
53411 
53412           // Mark the instance as stopped immediately, since we are
53413           // unregistering it below.
53414           //
53415           //  The StopDataSourceInstance above might have set the state to
53416           //  STOPPING so this condition isn't an else.
53417           if (it->second.state == DataSourceInstance::STOPPING)
53418             NotifyDataSourceStopped(producer_id, ds_inst_id);
53419         }
53420         it = ds_instances.erase(it);
53421         removed = true;
53422       } else {
53423         ++it;
53424       }
53425     }  // for (data_source_instances)
53426     if (removed)
53427       MaybeNotifyAllDataSourcesStarted(&kv.second);
53428   }  // for (tracing_session)
53429 
53430   for (auto it = data_sources_.begin(); it != data_sources_.end(); ++it) {
53431     if (it->second.producer_id == producer_id &&
53432         it->second.descriptor.name() == name) {
53433       data_sources_.erase(it);
53434       return;
53435     }
53436   }
53437 
53438   PERFETTO_DFATAL(
53439       "Tried to unregister a non-existent data source \"%s\" for "
53440       "producer %" PRIu16,
53441       name.c_str(), producer_id);
53442 }
53443 
SetupDataSource(const TraceConfig::DataSource & cfg_data_source,const TraceConfig::ProducerConfig & producer_config,const RegisteredDataSource & data_source,TracingSession * tracing_session)53444 TracingServiceImpl::DataSourceInstance* TracingServiceImpl::SetupDataSource(
53445     const TraceConfig::DataSource& cfg_data_source,
53446     const TraceConfig::ProducerConfig& producer_config,
53447     const RegisteredDataSource& data_source,
53448     TracingSession* tracing_session) {
53449   PERFETTO_DCHECK_THREAD(thread_checker_);
53450   ProducerEndpointImpl* producer = GetProducer(data_source.producer_id);
53451   PERFETTO_DCHECK(producer);
53452   // An existing producer that is not ftrace could have registered itself as
53453   // ftrace, we must not enable it in that case.
53454   if (lockdown_mode_ && producer->uid_ != uid_) {
53455     PERFETTO_DLOG("Lockdown mode: not enabling producer %hu", producer->id_);
53456     return nullptr;
53457   }
53458   // TODO(primiano): Add tests for registration ordering (data sources vs
53459   // consumers).
53460   if (!NameMatchesFilter(producer->name_,
53461                          cfg_data_source.producer_name_filter(),
53462                          cfg_data_source.producer_name_regex_filter())) {
53463     PERFETTO_DLOG("Data source: %s is filtered out for producer: %s",
53464                   cfg_data_source.config().name().c_str(),
53465                   producer->name_.c_str());
53466     return nullptr;
53467   }
53468 
53469   auto relative_buffer_id = cfg_data_source.config().target_buffer();
53470   if (relative_buffer_id >= tracing_session->num_buffers()) {
53471     PERFETTO_LOG(
53472         "The TraceConfig for DataSource %s specified a target_buffer out of "
53473         "bound (%d). Skipping it.",
53474         cfg_data_source.config().name().c_str(), relative_buffer_id);
53475     return nullptr;
53476   }
53477 
53478   // Create a copy of the DataSourceConfig specified in the trace config. This
53479   // will be passed to the producer after translating the |target_buffer| id.
53480   // The |target_buffer| parameter passed by the consumer in the trace config is
53481   // relative to the buffers declared in the same trace config. This has to be
53482   // translated to the global BufferID before passing it to the producers, which
53483   // don't know anything about tracing sessions and consumers.
53484 
53485   DataSourceInstanceID inst_id = ++last_data_source_instance_id_;
53486   auto insert_iter = tracing_session->data_source_instances.emplace(
53487       std::piecewise_construct,  //
53488       std::forward_as_tuple(producer->id_),
53489       std::forward_as_tuple(
53490           inst_id,
53491           cfg_data_source.config(),  //  Deliberate copy.
53492           data_source.descriptor.name(),
53493           data_source.descriptor.will_notify_on_start(),
53494           data_source.descriptor.will_notify_on_stop(),
53495           data_source.descriptor.handles_incremental_state_clear()));
53496   DataSourceInstance* ds_instance = &insert_iter->second;
53497 
53498   // New data source instance starts out in CONFIGURED state.
53499   if (tracing_session->consumer_maybe_null) {
53500     tracing_session->consumer_maybe_null->OnDataSourceInstanceStateChange(
53501         *producer, *ds_instance);
53502   }
53503 
53504   DataSourceConfig& ds_config = ds_instance->config;
53505   ds_config.set_trace_duration_ms(tracing_session->config.duration_ms());
53506   ds_config.set_stop_timeout_ms(tracing_session->data_source_stop_timeout_ms());
53507   ds_config.set_enable_extra_guardrails(
53508       tracing_session->config.enable_extra_guardrails());
53509   if (tracing_session->consumer_uid == 1066 /* AID_STATSD */ &&
53510       tracing_session->config.statsd_metadata().triggering_config_uid() !=
53511           2000 /* AID_SHELL */
53512       && tracing_session->config.statsd_metadata().triggering_config_uid() !=
53513              0 /* AID_ROOT */) {
53514     // StatsD can be triggered either by shell, root or an app that has DUMP and
53515     // USAGE_STATS permission. When triggered by shell or root, we do not want
53516     // to consider the trace a trusted system trace, as it was initiated by the
53517     // user. Otherwise, it has to come from an app with DUMP and
53518     // PACKAGE_USAGE_STATS, which has to be preinstalled and trusted by the
53519     // system.
53520     // Check for shell / root: https://bit.ly/3b7oZNi
53521     // Check for DUMP or PACKAGE_USAGE_STATS: https://bit.ly/3ep0NrR
53522     ds_config.set_session_initiator(
53523         DataSourceConfig::SESSION_INITIATOR_TRUSTED_SYSTEM);
53524   } else {
53525     // Unset in case the consumer set it.
53526     // We need to be able to trust this field.
53527     ds_config.set_session_initiator(
53528         DataSourceConfig::SESSION_INITIATOR_UNSPECIFIED);
53529   }
53530   ds_config.set_tracing_session_id(tracing_session->id);
53531   BufferID global_id = tracing_session->buffers_index[relative_buffer_id];
53532   PERFETTO_DCHECK(global_id);
53533   ds_config.set_target_buffer(global_id);
53534 
53535   PERFETTO_DLOG("Setting up data source %s with target buffer %" PRIu16,
53536                 ds_config.name().c_str(), global_id);
53537   if (!producer->shared_memory()) {
53538     // Determine the SMB page size. Must be an integer multiple of 4k.
53539     // As for the SMB size below, the decision tree is as follows:
53540     // 1. Give priority to what is defined in the trace config.
53541     // 2. If unset give priority to the hint passed by the producer.
53542     // 3. Keep within bounds and ensure it's a multiple of 4k.
53543     size_t page_size = producer_config.page_size_kb() * 1024;
53544     if (page_size == 0)
53545       page_size = producer->shmem_page_size_hint_bytes_;
53546 
53547     // Determine the SMB size. Must be an integer multiple of the SMB page size.
53548     // The decision tree is as follows:
53549     // 1. Give priority to what defined in the trace config.
53550     // 2. If unset give priority to the hint passed by the producer.
53551     // 3. Keep within bounds and ensure it's a multiple of the page size.
53552     size_t shm_size = producer_config.shm_size_kb() * 1024;
53553     if (shm_size == 0)
53554       shm_size = producer->shmem_size_hint_bytes_;
53555 
53556     auto valid_sizes = EnsureValidShmSizes(shm_size, page_size);
53557     if (valid_sizes != std::tie(shm_size, page_size)) {
53558       PERFETTO_DLOG(
53559           "Invalid configured SMB sizes: shm_size %zu page_size %zu. Falling "
53560           "back to shm_size %zu page_size %zu.",
53561           shm_size, page_size, std::get<0>(valid_sizes),
53562           std::get<1>(valid_sizes));
53563     }
53564     std::tie(shm_size, page_size) = valid_sizes;
53565 
53566     // TODO(primiano): right now Create() will suicide in case of OOM if the
53567     // mmap fails. We should instead gracefully fail the request and tell the
53568     // client to go away.
53569     PERFETTO_DLOG("Creating SMB of %zu KB for producer \"%s\"", shm_size / 1024,
53570                   producer->name_.c_str());
53571     auto shared_memory = shm_factory_->CreateSharedMemory(shm_size);
53572     producer->SetupSharedMemory(std::move(shared_memory), page_size,
53573                                 /*provided_by_producer=*/false);
53574   }
53575   producer->SetupDataSource(inst_id, ds_config);
53576   return ds_instance;
53577 }
53578 
53579 // Note: all the fields % *_trusted ones are untrusted, as in, the Producer
53580 // might be lying / returning garbage contents. |src| and |size| can be trusted
53581 // 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)53582 void TracingServiceImpl::CopyProducerPageIntoLogBuffer(
53583     ProducerID producer_id_trusted,
53584     uid_t producer_uid_trusted,
53585     WriterID writer_id,
53586     ChunkID chunk_id,
53587     BufferID buffer_id,
53588     uint16_t num_fragments,
53589     uint8_t chunk_flags,
53590     bool chunk_complete,
53591     const uint8_t* src,
53592     size_t size) {
53593   PERFETTO_DCHECK_THREAD(thread_checker_);
53594 
53595   ProducerEndpointImpl* producer = GetProducer(producer_id_trusted);
53596   if (!producer) {
53597     PERFETTO_DFATAL("Producer not found.");
53598     chunks_discarded_++;
53599     return;
53600   }
53601 
53602   TraceBuffer* buf = GetBufferByID(buffer_id);
53603   if (!buf) {
53604     PERFETTO_DLOG("Could not find target buffer %" PRIu16
53605                   " for producer %" PRIu16,
53606                   buffer_id, producer_id_trusted);
53607     chunks_discarded_++;
53608     return;
53609   }
53610 
53611   // Verify that the producer is actually allowed to write into the target
53612   // buffer specified in the request. This prevents a malicious producer from
53613   // injecting data into a log buffer that belongs to a tracing session the
53614   // producer is not part of.
53615   if (!producer->is_allowed_target_buffer(buffer_id)) {
53616     PERFETTO_ELOG("Producer %" PRIu16
53617                   " tried to write into forbidden target buffer %" PRIu16,
53618                   producer_id_trusted, buffer_id);
53619     PERFETTO_DFATAL("Forbidden target buffer");
53620     chunks_discarded_++;
53621     return;
53622   }
53623 
53624   // If the writer was registered by the producer, it should only write into the
53625   // buffer it was registered with.
53626   base::Optional<BufferID> associated_buffer =
53627       producer->buffer_id_for_writer(writer_id);
53628   if (associated_buffer && *associated_buffer != buffer_id) {
53629     PERFETTO_ELOG("Writer %" PRIu16 " of producer %" PRIu16
53630                   " was registered to write into target buffer %" PRIu16
53631                   ", but tried to write into buffer %" PRIu16,
53632                   writer_id, producer_id_trusted, *associated_buffer,
53633                   buffer_id);
53634     PERFETTO_DFATAL("Wrong target buffer");
53635     chunks_discarded_++;
53636     return;
53637   }
53638 
53639   buf->CopyChunkUntrusted(producer_id_trusted, producer_uid_trusted, writer_id,
53640                           chunk_id, num_fragments, chunk_flags, chunk_complete,
53641                           src, size);
53642 }
53643 
ApplyChunkPatches(ProducerID producer_id_trusted,const std::vector<CommitDataRequest::ChunkToPatch> & chunks_to_patch)53644 void TracingServiceImpl::ApplyChunkPatches(
53645     ProducerID producer_id_trusted,
53646     const std::vector<CommitDataRequest::ChunkToPatch>& chunks_to_patch) {
53647   PERFETTO_DCHECK_THREAD(thread_checker_);
53648 
53649   for (const auto& chunk : chunks_to_patch) {
53650     const ChunkID chunk_id = static_cast<ChunkID>(chunk.chunk_id());
53651     const WriterID writer_id = static_cast<WriterID>(chunk.writer_id());
53652     TraceBuffer* buf =
53653         GetBufferByID(static_cast<BufferID>(chunk.target_buffer()));
53654     static_assert(std::numeric_limits<ChunkID>::max() == kMaxChunkID,
53655                   "Add a '|| chunk_id > kMaxChunkID' below if this fails");
53656     if (!writer_id || writer_id > kMaxWriterID || !buf) {
53657       // This can genuinely happen when the trace is stopped. The producers
53658       // might see the stop signal with some delay and try to keep sending
53659       // patches left soon after.
53660       PERFETTO_DLOG(
53661           "Received invalid chunks_to_patch request from Producer: %" PRIu16
53662           ", BufferID: %" PRIu32 " ChunkdID: %" PRIu32 " WriterID: %" PRIu16,
53663           producer_id_trusted, chunk.target_buffer(), chunk_id, writer_id);
53664       patches_discarded_ += static_cast<uint64_t>(chunk.patches_size());
53665       continue;
53666     }
53667 
53668     // Note, there's no need to validate that the producer is allowed to write
53669     // to the specified buffer ID (or that it's the correct buffer ID for a
53670     // registered TraceWriter). That's because TraceBuffer uses the producer ID
53671     // and writer ID to look up the chunk to patch. If the producer specifies an
53672     // incorrect buffer, this lookup will fail and TraceBuffer will ignore the
53673     // patches. Because the producer ID is trusted, there's also no way for a
53674     // malicious producer to patch another producer's data.
53675 
53676     // Speculate on the fact that there are going to be a limited amount of
53677     // patches per request, so we can allocate the |patches| array on the stack.
53678     std::array<TraceBuffer::Patch, 1024> patches;  // Uninitialized.
53679     if (chunk.patches().size() > patches.size()) {
53680       PERFETTO_ELOG("Too many patches (%zu) batched in the same request",
53681                     patches.size());
53682       PERFETTO_DFATAL("Too many patches");
53683       patches_discarded_ += static_cast<uint64_t>(chunk.patches_size());
53684       continue;
53685     }
53686 
53687     size_t i = 0;
53688     for (const auto& patch : chunk.patches()) {
53689       const std::string& patch_data = patch.data();
53690       if (patch_data.size() != patches[i].data.size()) {
53691         PERFETTO_ELOG("Received patch from producer: %" PRIu16
53692                       " of unexpected size %zu",
53693                       producer_id_trusted, patch_data.size());
53694         patches_discarded_++;
53695         continue;
53696       }
53697       patches[i].offset_untrusted = patch.offset();
53698       memcpy(&patches[i].data[0], patch_data.data(), patches[i].data.size());
53699       i++;
53700     }
53701     buf->TryPatchChunkContents(producer_id_trusted, writer_id, chunk_id,
53702                                &patches[0], i, chunk.has_more_patches());
53703   }
53704 }
53705 
GetDetachedSession(uid_t uid,const std::string & key)53706 TracingServiceImpl::TracingSession* TracingServiceImpl::GetDetachedSession(
53707     uid_t uid,
53708     const std::string& key) {
53709   PERFETTO_DCHECK_THREAD(thread_checker_);
53710   for (auto& kv : tracing_sessions_) {
53711     TracingSession* session = &kv.second;
53712     if (session->consumer_uid == uid && session->detach_key == key) {
53713       PERFETTO_DCHECK(session->consumer_maybe_null == nullptr);
53714       return session;
53715     }
53716   }
53717   return nullptr;
53718 }
53719 
GetTracingSession(TracingSessionID tsid)53720 TracingServiceImpl::TracingSession* TracingServiceImpl::GetTracingSession(
53721     TracingSessionID tsid) {
53722   PERFETTO_DCHECK_THREAD(thread_checker_);
53723   auto it = tsid ? tracing_sessions_.find(tsid) : tracing_sessions_.end();
53724   if (it == tracing_sessions_.end())
53725     return nullptr;
53726   return &it->second;
53727 }
53728 
GetNextProducerID()53729 ProducerID TracingServiceImpl::GetNextProducerID() {
53730   PERFETTO_DCHECK_THREAD(thread_checker_);
53731   PERFETTO_CHECK(producers_.size() < kMaxProducerID);
53732   do {
53733     ++last_producer_id_;
53734   } while (producers_.count(last_producer_id_) || last_producer_id_ == 0);
53735   PERFETTO_DCHECK(last_producer_id_ > 0 && last_producer_id_ <= kMaxProducerID);
53736   return last_producer_id_;
53737 }
53738 
GetBufferByID(BufferID buffer_id)53739 TraceBuffer* TracingServiceImpl::GetBufferByID(BufferID buffer_id) {
53740   auto buf_iter = buffers_.find(buffer_id);
53741   if (buf_iter == buffers_.end())
53742     return nullptr;
53743   return &*buf_iter->second;
53744 }
53745 
OnStartTriggersTimeout(TracingSessionID tsid)53746 void TracingServiceImpl::OnStartTriggersTimeout(TracingSessionID tsid) {
53747   // Skip entirely the flush if the trace session doesn't exist anymore.
53748   // This is to prevent misleading error messages to be logged.
53749   //
53750   // if the trace has started from the trigger we rely on
53751   // the |stop_delay_ms| from the trigger so don't flush and
53752   // disable if we've moved beyond a CONFIGURED state
53753   auto* tracing_session_ptr = GetTracingSession(tsid);
53754   if (tracing_session_ptr &&
53755       tracing_session_ptr->state == TracingSession::CONFIGURED) {
53756     PERFETTO_DLOG("Disabling TracingSession %" PRIu64
53757                   " since no triggers activated.",
53758                   tsid);
53759     // No data should be returned from ReadBuffers() regardless of if we
53760     // call FreeBuffers() or DisableTracing(). This is because in
53761     // STOP_TRACING we need this promise in either case, and using
53762     // DisableTracing() allows a graceful shutdown. Consumers can follow
53763     // their normal path and check the buffers through ReadBuffers() and
53764     // the code won't hang because the tracing session will still be
53765     // alive just disabled.
53766     DisableTracing(tsid);
53767   }
53768 }
53769 
UpdateMemoryGuardrail()53770 void TracingServiceImpl::UpdateMemoryGuardrail() {
53771 #if PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
53772   uint64_t total_buffer_bytes = 0;
53773 
53774   // Sum up all the shared memory buffers.
53775   for (const auto& id_to_producer : producers_) {
53776     if (id_to_producer.second->shared_memory())
53777       total_buffer_bytes += id_to_producer.second->shared_memory()->size();
53778   }
53779 
53780   // Sum up all the trace buffers.
53781   for (const auto& id_to_buffer : buffers_) {
53782     total_buffer_bytes += id_to_buffer.second->size();
53783   }
53784 
53785   // Set the guard rail to 32MB + the sum of all the buffers over a 30 second
53786   // interval.
53787   uint64_t guardrail = base::kWatchdogDefaultMemorySlack + total_buffer_bytes;
53788   base::Watchdog::GetInstance()->SetMemoryLimit(guardrail, 30 * 1000);
53789 #endif
53790 }
53791 
PeriodicSnapshotTask(TracingSessionID tsid)53792 void TracingServiceImpl::PeriodicSnapshotTask(TracingSessionID tsid) {
53793   auto* tracing_session = GetTracingSession(tsid);
53794   if (!tracing_session)
53795     return;
53796   if (tracing_session->state != TracingSession::STARTED)
53797     return;
53798   tracing_session->should_emit_sync_marker = true;
53799   tracing_session->should_emit_stats = true;
53800   MaybeSnapshotClocksIntoRingBuffer(tracing_session);
53801 }
53802 
SnapshotLifecyleEvent(TracingSession * tracing_session,uint32_t field_id,bool snapshot_clocks)53803 void TracingServiceImpl::SnapshotLifecyleEvent(TracingSession* tracing_session,
53804                                                uint32_t field_id,
53805                                                bool snapshot_clocks) {
53806   // field_id should be an id of a field in TracingServiceEvent.
53807   auto& lifecycle_events = tracing_session->lifecycle_events;
53808   auto event_it =
53809       std::find_if(lifecycle_events.begin(), lifecycle_events.end(),
53810                    [field_id](const TracingSession::LifecycleEvent& event) {
53811                      return event.field_id == field_id;
53812                    });
53813 
53814   TracingSession::LifecycleEvent* event;
53815   if (event_it == lifecycle_events.end()) {
53816     lifecycle_events.emplace_back(field_id);
53817     event = &lifecycle_events.back();
53818   } else {
53819     event = &*event_it;
53820   }
53821 
53822   // Snapshot the clocks before capturing the timestamp for the event so we can
53823   // use this snapshot to resolve the event timestamp if necessary.
53824   if (snapshot_clocks)
53825     MaybeSnapshotClocksIntoRingBuffer(tracing_session);
53826 
53827   // Erase before emplacing to prevent a unncessary doubling of memory if
53828   // not needed.
53829   if (event->timestamps.size() >= event->max_size) {
53830     event->timestamps.erase_front(1 + event->timestamps.size() -
53831                                   event->max_size);
53832   }
53833   event->timestamps.emplace_back(base::GetBootTimeNs().count());
53834 }
53835 
MaybeSnapshotClocksIntoRingBuffer(TracingSession * tracing_session)53836 void TracingServiceImpl::MaybeSnapshotClocksIntoRingBuffer(
53837     TracingSession* tracing_session) {
53838   if (tracing_session->config.builtin_data_sources()
53839           .disable_clock_snapshotting()) {
53840     return;
53841   }
53842 
53843   // We are making an explicit copy of the latest snapshot (if it exists)
53844   // because SnapshotClocks reads this data and computes the drift based on its
53845   // content. If the clock drift is high enough, it will update the contents of
53846   // |snapshot| and return true. Otherwise, it will return false.
53847   TracingSession::ClockSnapshotData snapshot =
53848       tracing_session->clock_snapshot_ring_buffer.empty()
53849           ? TracingSession::ClockSnapshotData()
53850           : tracing_session->clock_snapshot_ring_buffer.back();
53851   bool did_update = SnapshotClocks(&snapshot);
53852   if (did_update) {
53853     // This means clocks drifted enough since last snapshot. See the comment
53854     // in SnapshotClocks.
53855     auto* snapshot_buffer = &tracing_session->clock_snapshot_ring_buffer;
53856 
53857     // Erase before emplacing to prevent a unncessary doubling of memory if
53858     // not needed.
53859     static constexpr uint32_t kClockSnapshotRingBufferSize = 16;
53860     if (snapshot_buffer->size() >= kClockSnapshotRingBufferSize) {
53861       snapshot_buffer->erase_front(1 + snapshot_buffer->size() -
53862                                    kClockSnapshotRingBufferSize);
53863     }
53864     snapshot_buffer->emplace_back(std::move(snapshot));
53865   }
53866 }
53867 
53868 // Returns true when the data in |snapshot_data| is updated with the new state
53869 // of the clocks and false otherwise.
SnapshotClocks(TracingSession::ClockSnapshotData * snapshot_data)53870 bool TracingServiceImpl::SnapshotClocks(
53871     TracingSession::ClockSnapshotData* snapshot_data) {
53872   // Minimum drift that justifies replacing a prior clock snapshot that hasn't
53873   // been emitted into the trace yet (see comment below).
53874   static constexpr int64_t kSignificantDriftNs = 10 * 1000 * 1000;  // 10 ms
53875 
53876   TracingSession::ClockSnapshotData new_snapshot_data;
53877 
53878 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) && \
53879     !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) &&   \
53880     !PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
53881   struct {
53882     clockid_t id;
53883     protos::pbzero::BuiltinClock type;
53884     struct timespec ts;
53885   } clocks[] = {
53886       {CLOCK_BOOTTIME, protos::pbzero::BUILTIN_CLOCK_BOOTTIME, {0, 0}},
53887       {CLOCK_REALTIME_COARSE,
53888        protos::pbzero::BUILTIN_CLOCK_REALTIME_COARSE,
53889        {0, 0}},
53890       {CLOCK_MONOTONIC_COARSE,
53891        protos::pbzero::BUILTIN_CLOCK_MONOTONIC_COARSE,
53892        {0, 0}},
53893       {CLOCK_REALTIME, protos::pbzero::BUILTIN_CLOCK_REALTIME, {0, 0}},
53894       {CLOCK_MONOTONIC, protos::pbzero::BUILTIN_CLOCK_MONOTONIC, {0, 0}},
53895       {CLOCK_MONOTONIC_RAW,
53896        protos::pbzero::BUILTIN_CLOCK_MONOTONIC_RAW,
53897        {0, 0}},
53898   };
53899   // First snapshot all the clocks as atomically as we can.
53900   for (auto& clock : clocks) {
53901     if (clock_gettime(clock.id, &clock.ts) == -1)
53902       PERFETTO_DLOG("clock_gettime failed for clock %d", clock.id);
53903   }
53904   for (auto& clock : clocks) {
53905     new_snapshot_data.push_back(std::make_pair(
53906         static_cast<uint32_t>(clock.type),
53907         static_cast<uint64_t>(base::FromPosixTimespec(clock.ts).count())));
53908   }
53909 #else  // OS_APPLE || OS_WIN && OS_NACL
53910   auto wall_time_ns = static_cast<uint64_t>(base::GetWallTimeNs().count());
53911   // The default trace clock is boot time, so we always need to emit a path to
53912   // it. However since we don't actually have a boot time source on these
53913   // platforms, pretend that wall time equals boot time.
53914   new_snapshot_data.push_back(
53915       std::make_pair(protos::pbzero::BUILTIN_CLOCK_BOOTTIME, wall_time_ns));
53916   new_snapshot_data.push_back(
53917       std::make_pair(protos::pbzero::BUILTIN_CLOCK_MONOTONIC, wall_time_ns));
53918 #endif
53919 
53920   // If we're about to update a session's latest clock snapshot that hasn't been
53921   // emitted into the trace yet, check whether the clocks have drifted enough to
53922   // warrant overriding the current snapshot values. The older snapshot would be
53923   // valid for a larger part of the currently buffered trace data because the
53924   // clock sync protocol in trace processor uses the latest clock <= timestamp
53925   // to translate times (see https://perfetto.dev/docs/concepts/clock-sync), so
53926   // we try to keep it if we can.
53927   if (!snapshot_data->empty()) {
53928     PERFETTO_DCHECK(snapshot_data->size() == new_snapshot_data.size());
53929     PERFETTO_DCHECK((*snapshot_data)[0].first ==
53930                     protos::gen::BUILTIN_CLOCK_BOOTTIME);
53931 
53932     bool update_snapshot = false;
53933     uint64_t old_boot_ns = (*snapshot_data)[0].second;
53934     uint64_t new_boot_ns = new_snapshot_data[0].second;
53935     int64_t boot_diff =
53936         static_cast<int64_t>(new_boot_ns) - static_cast<int64_t>(old_boot_ns);
53937 
53938     for (size_t i = 1; i < snapshot_data->size(); i++) {
53939       uint64_t old_ns = (*snapshot_data)[i].second;
53940       uint64_t new_ns = new_snapshot_data[i].second;
53941 
53942       int64_t diff =
53943           static_cast<int64_t>(new_ns) - static_cast<int64_t>(old_ns);
53944 
53945       // Compare the boottime delta against the delta of this clock.
53946       if (std::abs(boot_diff - diff) >= kSignificantDriftNs) {
53947         update_snapshot = true;
53948         break;
53949       }
53950     }
53951     if (!update_snapshot)
53952       return false;
53953     snapshot_data->clear();
53954   }
53955 
53956   *snapshot_data = std::move(new_snapshot_data);
53957   return true;
53958 }
53959 
EmitClockSnapshot(TracingSession * tracing_session,TracingSession::ClockSnapshotData snapshot_data,std::vector<TracePacket> * packets)53960 void TracingServiceImpl::EmitClockSnapshot(
53961     TracingSession* tracing_session,
53962     TracingSession::ClockSnapshotData snapshot_data,
53963     std::vector<TracePacket>* packets) {
53964   PERFETTO_DCHECK(!tracing_session->config.builtin_data_sources()
53965                        .disable_clock_snapshotting());
53966 
53967   protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
53968   auto* snapshot = packet->set_clock_snapshot();
53969 
53970   protos::gen::BuiltinClock trace_clock =
53971       tracing_session->config.builtin_data_sources().primary_trace_clock();
53972   if (!trace_clock)
53973     trace_clock = protos::gen::BUILTIN_CLOCK_BOOTTIME;
53974   snapshot->set_primary_trace_clock(
53975       static_cast<protos::pbzero::BuiltinClock>(trace_clock));
53976 
53977   for (auto& clock_id_and_ts : snapshot_data) {
53978     auto* c = snapshot->add_clocks();
53979     c->set_clock_id(clock_id_and_ts.first);
53980     c->set_timestamp(clock_id_and_ts.second);
53981   }
53982 
53983   packet->set_trusted_uid(static_cast<int32_t>(uid_));
53984   packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
53985   SerializeAndAppendPacket(packets, packet.SerializeAsArray());
53986 }
53987 
EmitSyncMarker(std::vector<TracePacket> * packets)53988 void TracingServiceImpl::EmitSyncMarker(std::vector<TracePacket>* packets) {
53989   // The sync marks are used to tokenize large traces efficiently.
53990   // See description in trace_packet.proto.
53991   if (sync_marker_packet_size_ == 0) {
53992     // The marker ABI expects that the marker is written after the uid.
53993     // Protozero guarantees that fields are written in the same order of the
53994     // calls. The ResynchronizeTraceStreamUsingSyncMarker test verifies the ABI.
53995     protozero::StaticBuffered<protos::pbzero::TracePacket> packet(
53996         &sync_marker_packet_[0], sizeof(sync_marker_packet_));
53997     packet->set_trusted_uid(static_cast<int32_t>(uid_));
53998     packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
53999 
54000     // Keep this last.
54001     packet->set_synchronization_marker(kSyncMarker, sizeof(kSyncMarker));
54002     sync_marker_packet_size_ = packet.Finalize();
54003   }
54004   packets->emplace_back();
54005   packets->back().AddSlice(&sync_marker_packet_[0], sync_marker_packet_size_);
54006 }
54007 
EmitStats(TracingSession * tracing_session,std::vector<TracePacket> * packets)54008 void TracingServiceImpl::EmitStats(TracingSession* tracing_session,
54009                                    std::vector<TracePacket>* packets) {
54010   protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
54011   packet->set_trusted_uid(static_cast<int32_t>(uid_));
54012   packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
54013   GetTraceStats(tracing_session).Serialize(packet->set_trace_stats());
54014   SerializeAndAppendPacket(packets, packet.SerializeAsArray());
54015 }
54016 
GetTraceStats(TracingSession * tracing_session)54017 TraceStats TracingServiceImpl::GetTraceStats(TracingSession* tracing_session) {
54018   TraceStats trace_stats;
54019   trace_stats.set_producers_connected(static_cast<uint32_t>(producers_.size()));
54020   trace_stats.set_producers_seen(last_producer_id_);
54021   trace_stats.set_data_sources_registered(
54022       static_cast<uint32_t>(data_sources_.size()));
54023   trace_stats.set_data_sources_seen(last_data_source_instance_id_);
54024   trace_stats.set_tracing_sessions(
54025       static_cast<uint32_t>(tracing_sessions_.size()));
54026   trace_stats.set_total_buffers(static_cast<uint32_t>(buffers_.size()));
54027   trace_stats.set_chunks_discarded(chunks_discarded_);
54028   trace_stats.set_patches_discarded(patches_discarded_);
54029   trace_stats.set_invalid_packets(tracing_session->invalid_packets);
54030 
54031   if (tracing_session->trace_filter) {
54032     auto* filt_stats = trace_stats.mutable_filter_stats();
54033     filt_stats->set_input_packets(tracing_session->filter_input_packets);
54034     filt_stats->set_input_bytes(tracing_session->filter_input_bytes);
54035     filt_stats->set_output_bytes(tracing_session->filter_output_bytes);
54036     filt_stats->set_errors(tracing_session->filter_errors);
54037   }
54038 
54039   for (BufferID buf_id : tracing_session->buffers_index) {
54040     TraceBuffer* buf = GetBufferByID(buf_id);
54041     if (!buf) {
54042       PERFETTO_DFATAL("Buffer not found.");
54043       continue;
54044     }
54045     *trace_stats.add_buffer_stats() = buf->stats();
54046   }  // for (buf in session).
54047   return trace_stats;
54048 }
54049 
MaybeEmitTraceConfig(TracingSession * tracing_session,std::vector<TracePacket> * packets)54050 void TracingServiceImpl::MaybeEmitTraceConfig(
54051     TracingSession* tracing_session,
54052     std::vector<TracePacket>* packets) {
54053   if (tracing_session->did_emit_config)
54054     return;
54055   tracing_session->did_emit_config = true;
54056   protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
54057   packet->set_trusted_uid(static_cast<int32_t>(uid_));
54058   packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
54059   tracing_session->config.Serialize(packet->set_trace_config());
54060   SerializeAndAppendPacket(packets, packet.SerializeAsArray());
54061 }
54062 
MaybeEmitSystemInfo(TracingSession * tracing_session,std::vector<TracePacket> * packets)54063 void TracingServiceImpl::MaybeEmitSystemInfo(
54064     TracingSession* tracing_session,
54065     std::vector<TracePacket>* packets) {
54066   if (tracing_session->did_emit_system_info)
54067     return;
54068   tracing_session->did_emit_system_info = true;
54069   protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
54070   auto* info = packet->set_system_info();
54071   info->set_tracing_service_version(base::GetVersionString());
54072 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
54073     !PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
54074   struct utsname uname_info;
54075   if (uname(&uname_info) == 0) {
54076     auto* utsname_info = info->set_utsname();
54077     utsname_info->set_sysname(uname_info.sysname);
54078     utsname_info->set_version(uname_info.version);
54079     utsname_info->set_machine(uname_info.machine);
54080     utsname_info->set_release(uname_info.release);
54081   }
54082 #endif  // !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
54083 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
54084   char value[PROP_VALUE_MAX];
54085   if (__system_property_get("ro.build.fingerprint", value)) {
54086     info->set_android_build_fingerprint(value);
54087   } else {
54088     PERFETTO_ELOG("Unable to read ro.build.fingerprint");
54089   }
54090   info->set_hz(sysconf(_SC_CLK_TCK));
54091 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
54092   packet->set_trusted_uid(static_cast<int32_t>(uid_));
54093   packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
54094   SerializeAndAppendPacket(packets, packet.SerializeAsArray());
54095 }
54096 
EmitLifecycleEvents(TracingSession * tracing_session,std::vector<TracePacket> * packets)54097 void TracingServiceImpl::EmitLifecycleEvents(
54098     TracingSession* tracing_session,
54099     std::vector<TracePacket>* packets) {
54100   using TimestampedPacket =
54101       std::pair<int64_t /* ts */, std::vector<uint8_t> /* serialized packet */>;
54102 
54103   std::vector<TimestampedPacket> timestamped_packets;
54104   for (auto& event : tracing_session->lifecycle_events) {
54105     for (int64_t ts : event.timestamps) {
54106       protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
54107       packet->set_timestamp(static_cast<uint64_t>(ts));
54108       packet->set_trusted_uid(static_cast<int32_t>(uid_));
54109       packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
54110 
54111       auto* service_event = packet->set_service_event();
54112       service_event->AppendVarInt(event.field_id, 1);
54113       timestamped_packets.emplace_back(ts, packet.SerializeAsArray());
54114     }
54115     event.timestamps.clear();
54116   }
54117 
54118   // We sort by timestamp here to ensure that the "sequence" of lifecycle
54119   // packets has monotonic timestamps like other sequences in the trace.
54120   // Note that these events could still be out of order with respect to other
54121   // events on the service packet sequence (e.g. trigger received packets).
54122   std::sort(timestamped_packets.begin(), timestamped_packets.end(),
54123             [](const TimestampedPacket& a, const TimestampedPacket& b) {
54124               return a.first < b.first;
54125             });
54126 
54127   for (const auto& pair : timestamped_packets)
54128     SerializeAndAppendPacket(packets, std::move(pair.second));
54129 }
54130 
EmitSeizedForBugreportLifecycleEvent(std::vector<TracePacket> * packets)54131 void TracingServiceImpl::EmitSeizedForBugreportLifecycleEvent(
54132     std::vector<TracePacket>* packets) {
54133   protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
54134   packet->set_timestamp(static_cast<uint64_t>(base::GetBootTimeNs().count()));
54135   packet->set_trusted_uid(static_cast<int32_t>(uid_));
54136   packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
54137   auto* service_event = packet->set_service_event();
54138   service_event->AppendVarInt(
54139       protos::pbzero::TracingServiceEvent::kSeizedForBugreportFieldNumber, 1);
54140   SerializeAndAppendPacket(packets, packet.SerializeAsArray());
54141 }
54142 
MaybeEmitReceivedTriggers(TracingSession * tracing_session,std::vector<TracePacket> * packets)54143 void TracingServiceImpl::MaybeEmitReceivedTriggers(
54144     TracingSession* tracing_session,
54145     std::vector<TracePacket>* packets) {
54146   PERFETTO_DCHECK(tracing_session->num_triggers_emitted_into_trace <=
54147                   tracing_session->received_triggers.size());
54148   for (size_t i = tracing_session->num_triggers_emitted_into_trace;
54149        i < tracing_session->received_triggers.size(); ++i) {
54150     const auto& info = tracing_session->received_triggers[i];
54151     protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
54152     auto* trigger = packet->set_trigger();
54153     trigger->set_trigger_name(info.trigger_name);
54154     trigger->set_producer_name(info.producer_name);
54155     trigger->set_trusted_producer_uid(static_cast<int32_t>(info.producer_uid));
54156 
54157     packet->set_timestamp(info.boot_time_ns);
54158     packet->set_trusted_uid(static_cast<int32_t>(uid_));
54159     packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
54160     SerializeAndAppendPacket(packets, packet.SerializeAsArray());
54161     ++tracing_session->num_triggers_emitted_into_trace;
54162   }
54163 }
54164 
MaybeSaveTraceForBugreport(std::function<void ()> callback)54165 bool TracingServiceImpl::MaybeSaveTraceForBugreport(
54166     std::function<void()> callback) {
54167   TracingSession* max_session = nullptr;
54168   TracingSessionID max_tsid = 0;
54169   for (auto& session_id_and_session : tracing_sessions_) {
54170     auto& session = session_id_and_session.second;
54171     const int32_t score = session.config.bugreport_score();
54172     // Exclude sessions with 0 (or below) score. By default tracing sessions
54173     // should NOT be eligible to be attached to bugreports.
54174     if (score <= 0 || session.state != TracingSession::STARTED)
54175       continue;
54176 
54177     // Also don't try to steal long traces with write_into_file if their content
54178     // has been already partially written into a file, as we would get partial
54179     // traces on both sides. We can't just copy the original file into the
54180     // bugreport because the file could be too big (GBs) for bugreports.
54181     // The only case where it's legit to steal traces with write_into_file, is
54182     // when the consumer specified a very large write_period_ms (e.g. 24h),
54183     // meaning that this is effectively a ring-buffer trace. Traceur (the
54184     // Android System Tracing app), which uses --detach, does this to have a
54185     // consistent invocation path for long-traces and ring-buffer-mode traces.
54186     if (session.write_into_file && session.bytes_written_into_file > 0)
54187       continue;
54188 
54189     // If we are already in the process of finalizing another trace for
54190     // bugreport, don't even start another one, as they would try to write onto
54191     // the same file.
54192     if (session.on_disable_callback_for_bugreport)
54193       return false;
54194 
54195     if (!max_session || score > max_session->config.bugreport_score()) {
54196       max_session = &session;
54197       max_tsid = session_id_and_session.first;
54198     }
54199   }
54200 
54201   // No eligible trace found.
54202   if (!max_session)
54203     return false;
54204 
54205   PERFETTO_LOG("Seizing trace for bugreport. tsid:%" PRIu64
54206                " state:%d wf:%d score:%d name:\"%s\"",
54207                max_tsid, max_session->state, !!max_session->write_into_file,
54208                max_session->config.bugreport_score(),
54209                max_session->config.unique_session_name().c_str());
54210 
54211   auto br_fd = CreateTraceFile(GetBugreportTmpPath(), /*overwrite=*/true);
54212   if (!br_fd)
54213     return false;
54214 
54215   if (max_session->write_into_file) {
54216     auto fd = *max_session->write_into_file;
54217     // If we are stealing a write_into_file session, add a marker that explains
54218     // why the trace has been stolen rather than creating an empty file. This is
54219     // only for write_into_file traces. A similar code path deals with the case
54220     // of reading-back a seized trace from IPC in ReadBuffers().
54221     if (!max_session->config.builtin_data_sources().disable_service_events()) {
54222       std::vector<TracePacket> packets;
54223       EmitSeizedForBugreportLifecycleEvent(&packets);
54224       for (auto& packet : packets) {
54225         char* preamble;
54226         size_t preamble_size = 0;
54227         std::tie(preamble, preamble_size) = packet.GetProtoPreamble();
54228         base::WriteAll(fd, preamble, preamble_size);
54229         for (const Slice& slice : packet.slices()) {
54230           base::WriteAll(fd, slice.start, slice.size);
54231         }
54232       }  // for (packets)
54233     }    // if (!disable_service_events())
54234   }      // if (max_session->write_into_file)
54235   max_session->write_into_file = std::move(br_fd);
54236   max_session->on_disable_callback_for_bugreport = std::move(callback);
54237   max_session->seized_for_bugreport = true;
54238 
54239   // Post a task to avoid that early FlushAndDisableTracing() failures invoke
54240   // the callback before we return. That would re-enter in a weird way the
54241   // callstack of the calling ConsumerEndpointImpl::SaveTraceForBugreport().
54242   auto weak_this = weak_ptr_factory_.GetWeakPtr();
54243   task_runner_->PostTask([weak_this, max_tsid] {
54244     if (weak_this)
54245       weak_this->FlushAndDisableTracing(max_tsid);
54246   });
54247   return true;
54248 }
54249 
MaybeLogUploadEvent(const TraceConfig & cfg,PerfettoStatsdAtom atom,const std::string & trigger_name)54250 void TracingServiceImpl::MaybeLogUploadEvent(const TraceConfig& cfg,
54251                                              PerfettoStatsdAtom atom,
54252                                              const std::string& trigger_name) {
54253   if (!ShouldLogEvent(cfg))
54254     return;
54255 
54256   // If the UUID is not set for some reason, don't log anything.
54257   if (cfg.trace_uuid_lsb() == 0 && cfg.trace_uuid_msb() == 0)
54258     return;
54259 
54260   android_stats::MaybeLogUploadEvent(atom, cfg.trace_uuid_lsb(),
54261                                      cfg.trace_uuid_msb(), trigger_name);
54262 }
54263 
MaybeLogTriggerEvent(const TraceConfig & cfg,PerfettoTriggerAtom atom,const std::string & trigger_name)54264 void TracingServiceImpl::MaybeLogTriggerEvent(const TraceConfig& cfg,
54265                                               PerfettoTriggerAtom atom,
54266                                               const std::string& trigger_name) {
54267   if (!ShouldLogEvent(cfg))
54268     return;
54269   android_stats::MaybeLogTriggerEvent(atom, trigger_name);
54270 }
54271 
PurgeExpiredAndCountTriggerInWindow(int64_t now_ns,uint64_t trigger_name_hash)54272 size_t TracingServiceImpl::PurgeExpiredAndCountTriggerInWindow(
54273     int64_t now_ns,
54274     uint64_t trigger_name_hash) {
54275   PERFETTO_DCHECK(
54276       std::is_sorted(trigger_history_.begin(), trigger_history_.end()));
54277   size_t remove_count = 0;
54278   size_t trigger_count = 0;
54279   for (const TriggerHistory& h : trigger_history_) {
54280     if (h.timestamp_ns < now_ns - trigger_window_ns_) {
54281       remove_count++;
54282     } else if (h.name_hash == trigger_name_hash) {
54283       trigger_count++;
54284     }
54285   }
54286   trigger_history_.erase_front(remove_count);
54287   return trigger_count;
54288 }
54289 
54290 ////////////////////////////////////////////////////////////////////////////////
54291 // TracingServiceImpl::ConsumerEndpointImpl implementation
54292 ////////////////////////////////////////////////////////////////////////////////
54293 
ConsumerEndpointImpl(TracingServiceImpl * service,base::TaskRunner * task_runner,Consumer * consumer,uid_t uid)54294 TracingServiceImpl::ConsumerEndpointImpl::ConsumerEndpointImpl(
54295     TracingServiceImpl* service,
54296     base::TaskRunner* task_runner,
54297     Consumer* consumer,
54298     uid_t uid)
54299     : task_runner_(task_runner),
54300       service_(service),
54301       consumer_(consumer),
54302       uid_(uid),
54303       weak_ptr_factory_(this) {}
54304 
~ConsumerEndpointImpl()54305 TracingServiceImpl::ConsumerEndpointImpl::~ConsumerEndpointImpl() {
54306   service_->DisconnectConsumer(this);
54307   consumer_->OnDisconnect();
54308 }
54309 
NotifyOnTracingDisabled(const std::string & error)54310 void TracingServiceImpl::ConsumerEndpointImpl::NotifyOnTracingDisabled(
54311     const std::string& error) {
54312   PERFETTO_DCHECK_THREAD(thread_checker_);
54313   auto weak_this = weak_ptr_factory_.GetWeakPtr();
54314   task_runner_->PostTask([weak_this, error /* deliberate copy */] {
54315     if (weak_this)
54316       weak_this->consumer_->OnTracingDisabled(error);
54317   });
54318 }
54319 
EnableTracing(const TraceConfig & cfg,base::ScopedFile fd)54320 void TracingServiceImpl::ConsumerEndpointImpl::EnableTracing(
54321     const TraceConfig& cfg,
54322     base::ScopedFile fd) {
54323   PERFETTO_DCHECK_THREAD(thread_checker_);
54324   auto status = service_->EnableTracing(this, cfg, std::move(fd));
54325   if (!status.ok())
54326     NotifyOnTracingDisabled(status.message());
54327 }
54328 
ChangeTraceConfig(const TraceConfig & cfg)54329 void TracingServiceImpl::ConsumerEndpointImpl::ChangeTraceConfig(
54330     const TraceConfig& cfg) {
54331   if (!tracing_session_id_) {
54332     PERFETTO_LOG(
54333         "Consumer called ChangeTraceConfig() but tracing was "
54334         "not active");
54335     return;
54336   }
54337   service_->ChangeTraceConfig(this, cfg);
54338 }
54339 
StartTracing()54340 void TracingServiceImpl::ConsumerEndpointImpl::StartTracing() {
54341   PERFETTO_DCHECK_THREAD(thread_checker_);
54342   if (!tracing_session_id_) {
54343     PERFETTO_LOG("Consumer called StartTracing() but tracing was not active");
54344     return;
54345   }
54346   service_->StartTracing(tracing_session_id_);
54347 }
54348 
DisableTracing()54349 void TracingServiceImpl::ConsumerEndpointImpl::DisableTracing() {
54350   PERFETTO_DCHECK_THREAD(thread_checker_);
54351   if (!tracing_session_id_) {
54352     PERFETTO_LOG("Consumer called DisableTracing() but tracing was not active");
54353     return;
54354   }
54355   service_->DisableTracing(tracing_session_id_);
54356 }
54357 
ReadBuffers()54358 void TracingServiceImpl::ConsumerEndpointImpl::ReadBuffers() {
54359   PERFETTO_DCHECK_THREAD(thread_checker_);
54360   if (!tracing_session_id_) {
54361     PERFETTO_LOG("Consumer called ReadBuffers() but tracing was not active");
54362     consumer_->OnTraceData({}, /* has_more = */ false);
54363     return;
54364   }
54365   if (!service_->ReadBuffers(tracing_session_id_, this)) {
54366     consumer_->OnTraceData({}, /* has_more = */ false);
54367   }
54368 }
54369 
FreeBuffers()54370 void TracingServiceImpl::ConsumerEndpointImpl::FreeBuffers() {
54371   PERFETTO_DCHECK_THREAD(thread_checker_);
54372   if (!tracing_session_id_) {
54373     PERFETTO_LOG("Consumer called FreeBuffers() but tracing was not active");
54374     return;
54375   }
54376   service_->FreeBuffers(tracing_session_id_);
54377   tracing_session_id_ = 0;
54378 }
54379 
Flush(uint32_t timeout_ms,FlushCallback callback)54380 void TracingServiceImpl::ConsumerEndpointImpl::Flush(uint32_t timeout_ms,
54381                                                      FlushCallback callback) {
54382   PERFETTO_DCHECK_THREAD(thread_checker_);
54383   if (!tracing_session_id_) {
54384     PERFETTO_LOG("Consumer called Flush() but tracing was not active");
54385     return;
54386   }
54387   service_->Flush(tracing_session_id_, timeout_ms, callback);
54388 }
54389 
Detach(const std::string & key)54390 void TracingServiceImpl::ConsumerEndpointImpl::Detach(const std::string& key) {
54391   PERFETTO_DCHECK_THREAD(thread_checker_);
54392   bool success = service_->DetachConsumer(this, key);
54393   auto weak_this = weak_ptr_factory_.GetWeakPtr();
54394   task_runner_->PostTask([weak_this, success] {
54395     if (weak_this)
54396       weak_this->consumer_->OnDetach(success);
54397   });
54398 }
54399 
Attach(const std::string & key)54400 void TracingServiceImpl::ConsumerEndpointImpl::Attach(const std::string& key) {
54401   PERFETTO_DCHECK_THREAD(thread_checker_);
54402   bool success = service_->AttachConsumer(this, key);
54403   auto weak_this = weak_ptr_factory_.GetWeakPtr();
54404   task_runner_->PostTask([weak_this, success] {
54405     if (!weak_this)
54406       return;
54407     Consumer* consumer = weak_this->consumer_;
54408     TracingSession* session =
54409         weak_this->service_->GetTracingSession(weak_this->tracing_session_id_);
54410     if (!session) {
54411       consumer->OnAttach(false, TraceConfig());
54412       return;
54413     }
54414     consumer->OnAttach(success, session->config);
54415   });
54416 }
54417 
GetTraceStats()54418 void TracingServiceImpl::ConsumerEndpointImpl::GetTraceStats() {
54419   PERFETTO_DCHECK_THREAD(thread_checker_);
54420   bool success = false;
54421   TraceStats stats;
54422   TracingSession* session = service_->GetTracingSession(tracing_session_id_);
54423   if (session) {
54424     success = true;
54425     stats = service_->GetTraceStats(session);
54426   }
54427   auto weak_this = weak_ptr_factory_.GetWeakPtr();
54428   task_runner_->PostTask([weak_this, success, stats] {
54429     if (weak_this)
54430       weak_this->consumer_->OnTraceStats(success, stats);
54431   });
54432 }
54433 
ObserveEvents(uint32_t events_mask)54434 void TracingServiceImpl::ConsumerEndpointImpl::ObserveEvents(
54435     uint32_t events_mask) {
54436   PERFETTO_DCHECK_THREAD(thread_checker_);
54437   observable_events_mask_ = events_mask;
54438   TracingSession* session = service_->GetTracingSession(tracing_session_id_);
54439   if (!session)
54440     return;
54441 
54442   if (observable_events_mask_ & ObservableEvents::TYPE_DATA_SOURCES_INSTANCES) {
54443     // Issue initial states.
54444     for (const auto& kv : session->data_source_instances) {
54445       ProducerEndpointImpl* producer = service_->GetProducer(kv.first);
54446       PERFETTO_DCHECK(producer);
54447       OnDataSourceInstanceStateChange(*producer, kv.second);
54448     }
54449   }
54450 
54451   // If the ObserveEvents() call happens after data sources have acked already
54452   // notify immediately.
54453   if (observable_events_mask_ &
54454       ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED) {
54455     service_->MaybeNotifyAllDataSourcesStarted(session);
54456   }
54457 }
54458 
OnDataSourceInstanceStateChange(const ProducerEndpointImpl & producer,const DataSourceInstance & instance)54459 void TracingServiceImpl::ConsumerEndpointImpl::OnDataSourceInstanceStateChange(
54460     const ProducerEndpointImpl& producer,
54461     const DataSourceInstance& instance) {
54462   if (!(observable_events_mask_ &
54463         ObservableEvents::TYPE_DATA_SOURCES_INSTANCES)) {
54464     return;
54465   }
54466 
54467   if (instance.state != DataSourceInstance::CONFIGURED &&
54468       instance.state != DataSourceInstance::STARTED &&
54469       instance.state != DataSourceInstance::STOPPED) {
54470     return;
54471   }
54472 
54473   auto* observable_events = AddObservableEvents();
54474   auto* change = observable_events->add_instance_state_changes();
54475   change->set_producer_name(producer.name_);
54476   change->set_data_source_name(instance.data_source_name);
54477   if (instance.state == DataSourceInstance::STARTED) {
54478     change->set_state(ObservableEvents::DATA_SOURCE_INSTANCE_STATE_STARTED);
54479   } else {
54480     change->set_state(ObservableEvents::DATA_SOURCE_INSTANCE_STATE_STOPPED);
54481   }
54482 }
54483 
OnAllDataSourcesStarted()54484 void TracingServiceImpl::ConsumerEndpointImpl::OnAllDataSourcesStarted() {
54485   if (!(observable_events_mask_ &
54486         ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED)) {
54487     return;
54488   }
54489   auto* observable_events = AddObservableEvents();
54490   observable_events->set_all_data_sources_started(true);
54491 }
54492 
54493 ObservableEvents*
AddObservableEvents()54494 TracingServiceImpl::ConsumerEndpointImpl::AddObservableEvents() {
54495   PERFETTO_DCHECK_THREAD(thread_checker_);
54496   if (!observable_events_) {
54497     observable_events_.reset(new ObservableEvents());
54498     auto weak_this = weak_ptr_factory_.GetWeakPtr();
54499     task_runner_->PostTask([weak_this] {
54500       if (!weak_this)
54501         return;
54502 
54503       // Move into a temporary to allow reentrancy in OnObservableEvents.
54504       auto observable_events = std::move(weak_this->observable_events_);
54505       weak_this->consumer_->OnObservableEvents(*observable_events);
54506     });
54507   }
54508   return observable_events_.get();
54509 }
54510 
QueryServiceState(QueryServiceStateCallback callback)54511 void TracingServiceImpl::ConsumerEndpointImpl::QueryServiceState(
54512     QueryServiceStateCallback callback) {
54513   PERFETTO_DCHECK_THREAD(thread_checker_);
54514   TracingServiceState svc_state;
54515 
54516   const auto& sessions = service_->tracing_sessions_;
54517   svc_state.set_tracing_service_version(base::GetVersionString());
54518   svc_state.set_num_sessions(static_cast<int>(sessions.size()));
54519 
54520   int num_started = 0;
54521   for (const auto& kv : sessions)
54522     num_started += kv.second.state == TracingSession::State::STARTED ? 1 : 0;
54523   svc_state.set_num_sessions_started(static_cast<int>(num_started));
54524 
54525   for (const auto& kv : service_->producers_) {
54526     auto* producer = svc_state.add_producers();
54527     producer->set_id(static_cast<int>(kv.first));
54528     producer->set_name(kv.second->name_);
54529     producer->set_sdk_version(kv.second->sdk_version_);
54530     producer->set_uid(static_cast<int32_t>(producer->uid()));
54531   }
54532 
54533   for (const auto& kv : service_->data_sources_) {
54534     const auto& registered_data_source = kv.second;
54535     auto* data_source = svc_state.add_data_sources();
54536     *data_source->mutable_ds_descriptor() = registered_data_source.descriptor;
54537     data_source->set_producer_id(
54538         static_cast<int>(registered_data_source.producer_id));
54539   }
54540   callback(/*success=*/true, svc_state);
54541 }
54542 
QueryCapabilities(QueryCapabilitiesCallback callback)54543 void TracingServiceImpl::ConsumerEndpointImpl::QueryCapabilities(
54544     QueryCapabilitiesCallback callback) {
54545   PERFETTO_DCHECK_THREAD(thread_checker_);
54546   TracingServiceCapabilities caps;
54547   caps.set_has_query_capabilities(true);
54548   caps.set_has_trace_config_output_path(true);
54549   caps.add_observable_events(ObservableEvents::TYPE_DATA_SOURCES_INSTANCES);
54550   caps.add_observable_events(ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED);
54551   static_assert(ObservableEvents::Type_MAX ==
54552                     ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED,
54553                 "");
54554   callback(caps);
54555 }
54556 
SaveTraceForBugreport(SaveTraceForBugreportCallback consumer_callback)54557 void TracingServiceImpl::ConsumerEndpointImpl::SaveTraceForBugreport(
54558     SaveTraceForBugreportCallback consumer_callback) {
54559   PERFETTO_DCHECK_THREAD(thread_checker_);
54560   auto on_complete_callback = [consumer_callback] {
54561     if (rename(GetBugreportTmpPath().c_str(), GetBugreportPath().c_str())) {
54562       consumer_callback(false, "rename(" + GetBugreportTmpPath() + ", " +
54563                                    GetBugreportPath() + ") failed (" +
54564                                    strerror(errno) + ")");
54565     } else {
54566       consumer_callback(true, GetBugreportPath());
54567     }
54568   };
54569   if (!service_->MaybeSaveTraceForBugreport(std::move(on_complete_callback))) {
54570     consumer_callback(false,
54571                       "No trace with TraceConfig.bugreport_score > 0 eligible "
54572                       "for bug reporting was found");
54573   }
54574 }
54575 
54576 ////////////////////////////////////////////////////////////////////////////////
54577 // TracingServiceImpl::ProducerEndpointImpl implementation
54578 ////////////////////////////////////////////////////////////////////////////////
54579 
ProducerEndpointImpl(ProducerID id,uid_t uid,TracingServiceImpl * service,base::TaskRunner * task_runner,Producer * producer,const std::string & producer_name,const std::string & sdk_version,bool in_process,bool smb_scraping_enabled)54580 TracingServiceImpl::ProducerEndpointImpl::ProducerEndpointImpl(
54581     ProducerID id,
54582     uid_t uid,
54583     TracingServiceImpl* service,
54584     base::TaskRunner* task_runner,
54585     Producer* producer,
54586     const std::string& producer_name,
54587     const std::string& sdk_version,
54588     bool in_process,
54589     bool smb_scraping_enabled)
54590     : id_(id),
54591       uid_(uid),
54592       service_(service),
54593       task_runner_(task_runner),
54594       producer_(producer),
54595       name_(producer_name),
54596       sdk_version_(sdk_version),
54597       in_process_(in_process),
54598       smb_scraping_enabled_(smb_scraping_enabled),
54599       weak_ptr_factory_(this) {}
54600 
~ProducerEndpointImpl()54601 TracingServiceImpl::ProducerEndpointImpl::~ProducerEndpointImpl() {
54602   service_->DisconnectProducer(id_);
54603   producer_->OnDisconnect();
54604 }
54605 
RegisterDataSource(const DataSourceDescriptor & desc)54606 void TracingServiceImpl::ProducerEndpointImpl::RegisterDataSource(
54607     const DataSourceDescriptor& desc) {
54608   PERFETTO_DCHECK_THREAD(thread_checker_);
54609   if (desc.name().empty()) {
54610     PERFETTO_DLOG("Received RegisterDataSource() with empty name");
54611     return;
54612   }
54613 
54614   service_->RegisterDataSource(id_, desc);
54615 }
54616 
UnregisterDataSource(const std::string & name)54617 void TracingServiceImpl::ProducerEndpointImpl::UnregisterDataSource(
54618     const std::string& name) {
54619   PERFETTO_DCHECK_THREAD(thread_checker_);
54620   service_->UnregisterDataSource(id_, name);
54621 }
54622 
RegisterTraceWriter(uint32_t writer_id,uint32_t target_buffer)54623 void TracingServiceImpl::ProducerEndpointImpl::RegisterTraceWriter(
54624     uint32_t writer_id,
54625     uint32_t target_buffer) {
54626   PERFETTO_DCHECK_THREAD(thread_checker_);
54627   writers_[static_cast<WriterID>(writer_id)] =
54628       static_cast<BufferID>(target_buffer);
54629 }
54630 
UnregisterTraceWriter(uint32_t writer_id)54631 void TracingServiceImpl::ProducerEndpointImpl::UnregisterTraceWriter(
54632     uint32_t writer_id) {
54633   PERFETTO_DCHECK_THREAD(thread_checker_);
54634   writers_.erase(static_cast<WriterID>(writer_id));
54635 }
54636 
CommitData(const CommitDataRequest & req_untrusted,CommitDataCallback callback)54637 void TracingServiceImpl::ProducerEndpointImpl::CommitData(
54638     const CommitDataRequest& req_untrusted,
54639     CommitDataCallback callback) {
54640   PERFETTO_DCHECK_THREAD(thread_checker_);
54641 
54642   if (metatrace::IsEnabled(metatrace::TAG_TRACE_SERVICE)) {
54643     PERFETTO_METATRACE_COUNTER(TAG_TRACE_SERVICE, TRACE_SERVICE_COMMIT_DATA,
54644                                EncodeCommitDataRequest(id_, req_untrusted));
54645   }
54646 
54647   if (!shared_memory_) {
54648     PERFETTO_DLOG(
54649         "Attempted to commit data before the shared memory was allocated.");
54650     return;
54651   }
54652   PERFETTO_DCHECK(shmem_abi_.is_valid());
54653   for (const auto& entry : req_untrusted.chunks_to_move()) {
54654     const uint32_t page_idx = entry.page();
54655     if (page_idx >= shmem_abi_.num_pages())
54656       continue;  // A buggy or malicious producer.
54657 
54658     SharedMemoryABI::Chunk chunk =
54659         shmem_abi_.TryAcquireChunkForReading(page_idx, entry.chunk());
54660     if (!chunk.is_valid()) {
54661       PERFETTO_DLOG("Asked to move chunk %d:%d, but it's not complete",
54662                     entry.page(), entry.chunk());
54663       continue;
54664     }
54665 
54666     // TryAcquireChunkForReading() has load-acquire semantics. Once acquired,
54667     // the ABI contract expects the producer to not touch the chunk anymore
54668     // (until the service marks that as free). This is why all the reads below
54669     // are just memory_order_relaxed. Also, the code here assumes that all this
54670     // data can be malicious and just gives up if anything is malformed.
54671     BufferID buffer_id = static_cast<BufferID>(entry.target_buffer());
54672     const SharedMemoryABI::ChunkHeader& chunk_header = *chunk.header();
54673     WriterID writer_id = chunk_header.writer_id.load(std::memory_order_relaxed);
54674     ChunkID chunk_id = chunk_header.chunk_id.load(std::memory_order_relaxed);
54675     auto packets = chunk_header.packets.load(std::memory_order_relaxed);
54676     uint16_t num_fragments = packets.count;
54677     uint8_t chunk_flags = packets.flags;
54678 
54679     service_->CopyProducerPageIntoLogBuffer(
54680         id_, uid_, writer_id, chunk_id, buffer_id, num_fragments, chunk_flags,
54681         /*chunk_complete=*/true, chunk.payload_begin(), chunk.payload_size());
54682 
54683     // This one has release-store semantics.
54684     shmem_abi_.ReleaseChunkAsFree(std::move(chunk));
54685   }  // for(chunks_to_move)
54686 
54687   service_->ApplyChunkPatches(id_, req_untrusted.chunks_to_patch());
54688 
54689   if (req_untrusted.flush_request_id()) {
54690     service_->NotifyFlushDoneForProducer(id_, req_untrusted.flush_request_id());
54691   }
54692 
54693   // Keep this invocation last. ProducerIPCService::CommitData() relies on this
54694   // callback being invoked within the same callstack and not posted. If this
54695   // changes, the code there needs to be changed accordingly.
54696   if (callback)
54697     callback();
54698 }
54699 
SetupSharedMemory(std::unique_ptr<SharedMemory> shared_memory,size_t page_size_bytes,bool provided_by_producer)54700 void TracingServiceImpl::ProducerEndpointImpl::SetupSharedMemory(
54701     std::unique_ptr<SharedMemory> shared_memory,
54702     size_t page_size_bytes,
54703     bool provided_by_producer) {
54704   PERFETTO_DCHECK(!shared_memory_ && !shmem_abi_.is_valid());
54705   PERFETTO_DCHECK(page_size_bytes % 1024 == 0);
54706 
54707   shared_memory_ = std::move(shared_memory);
54708   shared_buffer_page_size_kb_ = page_size_bytes / 1024;
54709   is_shmem_provided_by_producer_ = provided_by_producer;
54710 
54711   shmem_abi_.Initialize(reinterpret_cast<uint8_t*>(shared_memory_->start()),
54712                         shared_memory_->size(),
54713                         shared_buffer_page_size_kb() * 1024);
54714   if (in_process_) {
54715     inproc_shmem_arbiter_.reset(new SharedMemoryArbiterImpl(
54716         shared_memory_->start(), shared_memory_->size(),
54717         shared_buffer_page_size_kb_ * 1024, this, task_runner_));
54718     inproc_shmem_arbiter_->SetDirectSMBPatchingSupportedByService();
54719   }
54720 
54721   OnTracingSetup();
54722   service_->UpdateMemoryGuardrail();
54723 }
54724 
shared_memory() const54725 SharedMemory* TracingServiceImpl::ProducerEndpointImpl::shared_memory() const {
54726   PERFETTO_DCHECK_THREAD(thread_checker_);
54727   return shared_memory_.get();
54728 }
54729 
shared_buffer_page_size_kb() const54730 size_t TracingServiceImpl::ProducerEndpointImpl::shared_buffer_page_size_kb()
54731     const {
54732   return shared_buffer_page_size_kb_;
54733 }
54734 
ActivateTriggers(const std::vector<std::string> & triggers)54735 void TracingServiceImpl::ProducerEndpointImpl::ActivateTriggers(
54736     const std::vector<std::string>& triggers) {
54737   service_->ActivateTriggers(id_, triggers);
54738 }
54739 
StopDataSource(DataSourceInstanceID ds_inst_id)54740 void TracingServiceImpl::ProducerEndpointImpl::StopDataSource(
54741     DataSourceInstanceID ds_inst_id) {
54742   // TODO(primiano): When we'll support tearing down the SMB, at this point we
54743   // should send the Producer a TearDownTracing if all its data sources have
54744   // been disabled (see b/77532839 and aosp/655179 PS1).
54745   PERFETTO_DCHECK_THREAD(thread_checker_);
54746   auto weak_this = weak_ptr_factory_.GetWeakPtr();
54747   task_runner_->PostTask([weak_this, ds_inst_id] {
54748     if (weak_this)
54749       weak_this->producer_->StopDataSource(ds_inst_id);
54750   });
54751 }
54752 
54753 SharedMemoryArbiter*
MaybeSharedMemoryArbiter()54754 TracingServiceImpl::ProducerEndpointImpl::MaybeSharedMemoryArbiter() {
54755   if (!inproc_shmem_arbiter_) {
54756     PERFETTO_FATAL(
54757         "The in-process SharedMemoryArbiter can only be used when "
54758         "CreateProducer has been called with in_process=true and after tracing "
54759         "has started.");
54760   }
54761 
54762   PERFETTO_DCHECK(in_process_);
54763   return inproc_shmem_arbiter_.get();
54764 }
54765 
IsShmemProvidedByProducer() const54766 bool TracingServiceImpl::ProducerEndpointImpl::IsShmemProvidedByProducer()
54767     const {
54768   return is_shmem_provided_by_producer_;
54769 }
54770 
54771 // Can be called on any thread.
54772 std::unique_ptr<TraceWriter>
CreateTraceWriter(BufferID buf_id,BufferExhaustedPolicy buffer_exhausted_policy)54773 TracingServiceImpl::ProducerEndpointImpl::CreateTraceWriter(
54774     BufferID buf_id,
54775     BufferExhaustedPolicy buffer_exhausted_policy) {
54776   PERFETTO_DCHECK(MaybeSharedMemoryArbiter());
54777   return MaybeSharedMemoryArbiter()->CreateTraceWriter(buf_id,
54778                                                        buffer_exhausted_policy);
54779 }
54780 
NotifyFlushComplete(FlushRequestID id)54781 void TracingServiceImpl::ProducerEndpointImpl::NotifyFlushComplete(
54782     FlushRequestID id) {
54783   PERFETTO_DCHECK_THREAD(thread_checker_);
54784   PERFETTO_DCHECK(MaybeSharedMemoryArbiter());
54785   return MaybeSharedMemoryArbiter()->NotifyFlushComplete(id);
54786 }
54787 
OnTracingSetup()54788 void TracingServiceImpl::ProducerEndpointImpl::OnTracingSetup() {
54789   auto weak_this = weak_ptr_factory_.GetWeakPtr();
54790   task_runner_->PostTask([weak_this] {
54791     if (weak_this)
54792       weak_this->producer_->OnTracingSetup();
54793   });
54794 }
54795 
Flush(FlushRequestID flush_request_id,const std::vector<DataSourceInstanceID> & data_sources)54796 void TracingServiceImpl::ProducerEndpointImpl::Flush(
54797     FlushRequestID flush_request_id,
54798     const std::vector<DataSourceInstanceID>& data_sources) {
54799   PERFETTO_DCHECK_THREAD(thread_checker_);
54800   auto weak_this = weak_ptr_factory_.GetWeakPtr();
54801   task_runner_->PostTask([weak_this, flush_request_id, data_sources] {
54802     if (weak_this) {
54803       weak_this->producer_->Flush(flush_request_id, data_sources.data(),
54804                                   data_sources.size());
54805     }
54806   });
54807 }
54808 
SetupDataSource(DataSourceInstanceID ds_id,const DataSourceConfig & config)54809 void TracingServiceImpl::ProducerEndpointImpl::SetupDataSource(
54810     DataSourceInstanceID ds_id,
54811     const DataSourceConfig& config) {
54812   PERFETTO_DCHECK_THREAD(thread_checker_);
54813   allowed_target_buffers_.insert(static_cast<BufferID>(config.target_buffer()));
54814   auto weak_this = weak_ptr_factory_.GetWeakPtr();
54815   task_runner_->PostTask([weak_this, ds_id, config] {
54816     if (weak_this)
54817       weak_this->producer_->SetupDataSource(ds_id, std::move(config));
54818   });
54819 }
54820 
StartDataSource(DataSourceInstanceID ds_id,const DataSourceConfig & config)54821 void TracingServiceImpl::ProducerEndpointImpl::StartDataSource(
54822     DataSourceInstanceID ds_id,
54823     const DataSourceConfig& config) {
54824   PERFETTO_DCHECK_THREAD(thread_checker_);
54825   auto weak_this = weak_ptr_factory_.GetWeakPtr();
54826   task_runner_->PostTask([weak_this, ds_id, config] {
54827     if (weak_this)
54828       weak_this->producer_->StartDataSource(ds_id, std::move(config));
54829   });
54830 }
54831 
NotifyDataSourceStarted(DataSourceInstanceID data_source_id)54832 void TracingServiceImpl::ProducerEndpointImpl::NotifyDataSourceStarted(
54833     DataSourceInstanceID data_source_id) {
54834   PERFETTO_DCHECK_THREAD(thread_checker_);
54835   service_->NotifyDataSourceStarted(id_, data_source_id);
54836 }
54837 
NotifyDataSourceStopped(DataSourceInstanceID data_source_id)54838 void TracingServiceImpl::ProducerEndpointImpl::NotifyDataSourceStopped(
54839     DataSourceInstanceID data_source_id) {
54840   PERFETTO_DCHECK_THREAD(thread_checker_);
54841   service_->NotifyDataSourceStopped(id_, data_source_id);
54842 }
54843 
OnFreeBuffers(const std::vector<BufferID> & target_buffers)54844 void TracingServiceImpl::ProducerEndpointImpl::OnFreeBuffers(
54845     const std::vector<BufferID>& target_buffers) {
54846   if (allowed_target_buffers_.empty())
54847     return;
54848   for (BufferID buffer : target_buffers)
54849     allowed_target_buffers_.erase(buffer);
54850 }
54851 
ClearIncrementalState(const std::vector<DataSourceInstanceID> & data_sources)54852 void TracingServiceImpl::ProducerEndpointImpl::ClearIncrementalState(
54853     const std::vector<DataSourceInstanceID>& data_sources) {
54854   PERFETTO_DCHECK_THREAD(thread_checker_);
54855   auto weak_this = weak_ptr_factory_.GetWeakPtr();
54856   task_runner_->PostTask([weak_this, data_sources] {
54857     if (weak_this) {
54858       weak_this->producer_->ClearIncrementalState(data_sources.data(),
54859                                                   data_sources.size());
54860     }
54861   });
54862 }
54863 
Sync(std::function<void ()> callback)54864 void TracingServiceImpl::ProducerEndpointImpl::Sync(
54865     std::function<void()> callback) {
54866   task_runner_->PostTask(callback);
54867 }
54868 
54869 ////////////////////////////////////////////////////////////////////////////////
54870 // TracingServiceImpl::TracingSession implementation
54871 ////////////////////////////////////////////////////////////////////////////////
54872 
TracingSession(TracingSessionID session_id,ConsumerEndpointImpl * consumer,const TraceConfig & new_config,base::TaskRunner * task_runner)54873 TracingServiceImpl::TracingSession::TracingSession(
54874     TracingSessionID session_id,
54875     ConsumerEndpointImpl* consumer,
54876     const TraceConfig& new_config,
54877     base::TaskRunner* task_runner)
54878     : id(session_id),
54879       consumer_maybe_null(consumer),
54880       consumer_uid(consumer->uid_),
54881       config(new_config),
54882       snapshot_periodic_task(task_runner) {
54883   // all_data_sources_flushed is special because we store up to 64 events of
54884   // this type. Other events will go through the default case in
54885   // SnapshotLifecycleEvent() where they will be given a max history of 1.
54886   lifecycle_events.emplace_back(
54887       protos::pbzero::TracingServiceEvent::kAllDataSourcesFlushedFieldNumber,
54888       64 /* max_size */);
54889 }
54890 
54891 }  // namespace perfetto
54892 // gen_amalgamated begin source: src/tracing/internal/in_process_tracing_backend.cc
54893 /*
54894  * Copyright (C) 2019 The Android Open Source Project
54895  *
54896  * Licensed under the Apache License, Version 2.0 (the "License");
54897  * you may not use this file except in compliance with the License.
54898  * You may obtain a copy of the License at
54899  *
54900  *      http://www.apache.org/licenses/LICENSE-2.0
54901  *
54902  * Unless required by applicable law or agreed to in writing, software
54903  * distributed under the License is distributed on an "AS IS" BASIS,
54904  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
54905  * See the License for the specific language governing permissions and
54906  * limitations under the License.
54907  */
54908 
54909 // gen_amalgamated expanded: #include "perfetto/tracing/internal/in_process_tracing_backend.h"
54910 
54911 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
54912 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
54913 // gen_amalgamated expanded: #include "perfetto/ext/base/paged_memory.h"
54914 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
54915 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
54916 
54917 // TODO(primiano): When the in-process backend is used, we should never end up
54918 // in a situation where the thread where the TracingService and Producer live
54919 // writes a packet and hence can get into the GetNewChunk() stall.
54920 // This would happen only if the API client code calls Trace() from one of the
54921 // callbacks it receives (e.g. OnStart(), OnStop()). We should either cause a
54922 // hard crash or ignore traces from that thread if that happens, because it
54923 // will deadlock (the Service will never free up the SMB because won't ever get
54924 // to run the task).
54925 
54926 namespace perfetto {
54927 namespace internal {
54928 
54929 namespace {
54930 
54931 class InProcessShm : public SharedMemory {
54932  public:
54933   explicit InProcessShm(size_t size);
54934   ~InProcessShm() override;
54935   void* start() const override;
54936   size_t size() const override;
54937 
54938  private:
54939   base::PagedMemory mem_;
54940 };
54941 
54942 class InProcessShmFactory : public SharedMemory::Factory {
54943  public:
54944   ~InProcessShmFactory() override;
54945   std::unique_ptr<SharedMemory> CreateSharedMemory(size_t) override;
54946 };
54947 
54948 InProcessShm::~InProcessShm() = default;
54949 
InProcessShm(size_t size)54950 InProcessShm::InProcessShm(size_t size)
54951     : mem_(base::PagedMemory::Allocate(size)) {}
54952 
start() const54953 void* InProcessShm::start() const {
54954   return mem_.Get();
54955 }
54956 
size() const54957 size_t InProcessShm::size() const {
54958   return mem_.size();
54959 }
54960 
54961 InProcessShmFactory::~InProcessShmFactory() = default;
CreateSharedMemory(size_t size)54962 std::unique_ptr<SharedMemory> InProcessShmFactory::CreateSharedMemory(
54963     size_t size) {
54964   return std::unique_ptr<SharedMemory>(new InProcessShm(size));
54965 }
54966 
54967 }  // namespace
54968 
54969 // static
GetInstance()54970 TracingBackend* InProcessTracingBackend::GetInstance() {
54971   static auto* instance = new InProcessTracingBackend();
54972   return instance;
54973 }
54974 
InProcessTracingBackend()54975 InProcessTracingBackend::InProcessTracingBackend() {}
54976 
ConnectProducer(const ConnectProducerArgs & args)54977 std::unique_ptr<ProducerEndpoint> InProcessTracingBackend::ConnectProducer(
54978     const ConnectProducerArgs& args) {
54979   PERFETTO_DCHECK(args.task_runner->RunsTasksOnCurrentThread());
54980 
54981   // This should never happen as we can have at most one in-process backend.
54982   if (service_)
54983     PERFETTO_FATAL("InProcessTracingBackend initialized twice");
54984 
54985   return GetOrCreateService(args.task_runner)
54986       ->ConnectProducer(args.producer, /*uid=*/0, args.producer_name,
54987                         args.shmem_size_hint_bytes,
54988                         /*in_process=*/true,
54989                         TracingService::ProducerSMBScrapingMode::kEnabled,
54990                         args.shmem_page_size_hint_bytes);
54991 }
54992 
ConnectConsumer(const ConnectConsumerArgs & args)54993 std::unique_ptr<ConsumerEndpoint> InProcessTracingBackend::ConnectConsumer(
54994     const ConnectConsumerArgs& args) {
54995   return GetOrCreateService(args.task_runner)
54996       ->ConnectConsumer(args.consumer, /*uid=*/0);
54997 }
54998 
GetOrCreateService(base::TaskRunner * task_runner)54999 TracingService* InProcessTracingBackend::GetOrCreateService(
55000     base::TaskRunner* task_runner) {
55001   if (!service_) {
55002     std::unique_ptr<InProcessShmFactory> shm(new InProcessShmFactory());
55003     service_ = TracingService::CreateInstance(std::move(shm), task_runner);
55004     service_->SetSMBScrapingEnabled(true);
55005   }
55006   return service_.get();
55007 }
55008 
55009 }  // namespace internal
55010 }  // namespace perfetto
55011 // gen_amalgamated begin source: gen/protos/perfetto/ipc/consumer_port.gen.cc
55012 // gen_amalgamated begin header: gen/protos/perfetto/ipc/consumer_port.gen.h
55013 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
55014 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_CONSUMER_PORT_PROTO_CPP_H_
55015 #define PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_CONSUMER_PORT_PROTO_CPP_H_
55016 
55017 #include <stdint.h>
55018 #include <bitset>
55019 #include <vector>
55020 #include <string>
55021 #include <type_traits>
55022 
55023 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
55024 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
55025 // gen_amalgamated expanded: #include "perfetto/base/export.h"
55026 
55027 namespace perfetto {
55028 namespace protos {
55029 namespace gen {
55030 class SaveTraceForBugreportResponse;
55031 class SaveTraceForBugreportRequest;
55032 class QueryCapabilitiesResponse;
55033 class TracingServiceCapabilities;
55034 class QueryCapabilitiesRequest;
55035 class QueryServiceStateResponse;
55036 class TracingServiceState;
55037 class TracingServiceState_DataSource;
55038 class DataSourceDescriptor;
55039 class TracingServiceState_Producer;
55040 class QueryServiceStateRequest;
55041 class ObserveEventsResponse;
55042 class ObservableEvents;
55043 class ObservableEvents_DataSourceInstanceStateChange;
55044 class ObserveEventsRequest;
55045 class GetTraceStatsResponse;
55046 class TraceStats;
55047 class TraceStats_FilterStats;
55048 class TraceStats_BufferStats;
55049 class GetTraceStatsRequest;
55050 class AttachResponse;
55051 class TraceConfig;
55052 class TraceConfig_TraceFilter;
55053 class TraceConfig_IncidentReportConfig;
55054 class TraceConfig_IncrementalStateConfig;
55055 class TraceConfig_TriggerConfig;
55056 class TraceConfig_TriggerConfig_Trigger;
55057 class TraceConfig_GuardrailOverrides;
55058 class TraceConfig_StatsdMetadata;
55059 class TraceConfig_ProducerConfig;
55060 class TraceConfig_BuiltinDataSource;
55061 class TraceConfig_DataSource;
55062 class DataSourceConfig;
55063 class TestConfig;
55064 class TestConfig_DummyFields;
55065 class InterceptorConfig;
55066 class ChromeConfig;
55067 class TraceConfig_BufferConfig;
55068 class AttachRequest;
55069 class DetachResponse;
55070 class DetachRequest;
55071 class FlushResponse;
55072 class FlushRequest;
55073 class FreeBuffersResponse;
55074 class FreeBuffersRequest;
55075 class ReadBuffersResponse;
55076 class ReadBuffersResponse_Slice;
55077 class ReadBuffersRequest;
55078 class DisableTracingResponse;
55079 class DisableTracingRequest;
55080 class ChangeTraceConfigResponse;
55081 class ChangeTraceConfigRequest;
55082 class StartTracingResponse;
55083 class StartTracingRequest;
55084 class EnableTracingResponse;
55085 class EnableTracingRequest;
55086 enum ObservableEvents_Type : int;
55087 enum ObservableEvents_DataSourceInstanceState : int;
55088 enum TraceConfig_LockdownModeOperation : int;
55089 enum TraceConfig_CompressionType : int;
55090 enum TraceConfig_StatsdLogging : int;
55091 enum TraceConfig_TriggerConfig_TriggerMode : int;
55092 enum BuiltinClock : int;
55093 enum DataSourceConfig_SessionInitiator : int;
55094 enum ChromeConfig_ClientPriority : int;
55095 enum TraceConfig_BufferConfig_FillPolicy : int;
55096 }  // namespace perfetto
55097 }  // namespace protos
55098 }  // namespace gen
55099 
55100 namespace protozero {
55101 class Message;
55102 }  // namespace protozero
55103 
55104 namespace perfetto {
55105 namespace protos {
55106 namespace gen {
55107 
55108 class PERFETTO_EXPORT SaveTraceForBugreportResponse : public ::protozero::CppMessageObj {
55109  public:
55110   enum FieldNumbers {
55111     kSuccessFieldNumber = 1,
55112     kMsgFieldNumber = 2,
55113   };
55114 
55115   SaveTraceForBugreportResponse();
55116   ~SaveTraceForBugreportResponse() override;
55117   SaveTraceForBugreportResponse(SaveTraceForBugreportResponse&&) noexcept;
55118   SaveTraceForBugreportResponse& operator=(SaveTraceForBugreportResponse&&);
55119   SaveTraceForBugreportResponse(const SaveTraceForBugreportResponse&);
55120   SaveTraceForBugreportResponse& operator=(const SaveTraceForBugreportResponse&);
55121   bool operator==(const SaveTraceForBugreportResponse&) const;
operator !=(const SaveTraceForBugreportResponse & other) const55122   bool operator!=(const SaveTraceForBugreportResponse& other) const { return !(*this == other); }
55123 
55124   bool ParseFromArray(const void*, size_t) override;
55125   std::string SerializeAsString() const override;
55126   std::vector<uint8_t> SerializeAsArray() const override;
55127   void Serialize(::protozero::Message*) const;
55128 
has_success() const55129   bool has_success() const { return _has_field_[1]; }
success() const55130   bool success() const { return success_; }
set_success(bool value)55131   void set_success(bool value) { success_ = value; _has_field_.set(1); }
55132 
has_msg() const55133   bool has_msg() const { return _has_field_[2]; }
msg() const55134   const std::string& msg() const { return msg_; }
set_msg(const std::string & value)55135   void set_msg(const std::string& value) { msg_ = value; _has_field_.set(2); }
55136 
55137  private:
55138   bool success_{};
55139   std::string msg_{};
55140 
55141   // Allows to preserve unknown protobuf fields for compatibility
55142   // with future versions of .proto files.
55143   std::string unknown_fields_;
55144 
55145   std::bitset<3> _has_field_{};
55146 };
55147 
55148 
55149 class PERFETTO_EXPORT SaveTraceForBugreportRequest : public ::protozero::CppMessageObj {
55150  public:
55151   enum FieldNumbers {
55152   };
55153 
55154   SaveTraceForBugreportRequest();
55155   ~SaveTraceForBugreportRequest() override;
55156   SaveTraceForBugreportRequest(SaveTraceForBugreportRequest&&) noexcept;
55157   SaveTraceForBugreportRequest& operator=(SaveTraceForBugreportRequest&&);
55158   SaveTraceForBugreportRequest(const SaveTraceForBugreportRequest&);
55159   SaveTraceForBugreportRequest& operator=(const SaveTraceForBugreportRequest&);
55160   bool operator==(const SaveTraceForBugreportRequest&) const;
operator !=(const SaveTraceForBugreportRequest & other) const55161   bool operator!=(const SaveTraceForBugreportRequest& other) const { return !(*this == other); }
55162 
55163   bool ParseFromArray(const void*, size_t) override;
55164   std::string SerializeAsString() const override;
55165   std::vector<uint8_t> SerializeAsArray() const override;
55166   void Serialize(::protozero::Message*) const;
55167 
55168  private:
55169 
55170   // Allows to preserve unknown protobuf fields for compatibility
55171   // with future versions of .proto files.
55172   std::string unknown_fields_;
55173 
55174   std::bitset<2> _has_field_{};
55175 };
55176 
55177 
55178 class PERFETTO_EXPORT QueryCapabilitiesResponse : public ::protozero::CppMessageObj {
55179  public:
55180   enum FieldNumbers {
55181     kCapabilitiesFieldNumber = 1,
55182   };
55183 
55184   QueryCapabilitiesResponse();
55185   ~QueryCapabilitiesResponse() override;
55186   QueryCapabilitiesResponse(QueryCapabilitiesResponse&&) noexcept;
55187   QueryCapabilitiesResponse& operator=(QueryCapabilitiesResponse&&);
55188   QueryCapabilitiesResponse(const QueryCapabilitiesResponse&);
55189   QueryCapabilitiesResponse& operator=(const QueryCapabilitiesResponse&);
55190   bool operator==(const QueryCapabilitiesResponse&) const;
operator !=(const QueryCapabilitiesResponse & other) const55191   bool operator!=(const QueryCapabilitiesResponse& other) const { return !(*this == other); }
55192 
55193   bool ParseFromArray(const void*, size_t) override;
55194   std::string SerializeAsString() const override;
55195   std::vector<uint8_t> SerializeAsArray() const override;
55196   void Serialize(::protozero::Message*) const;
55197 
has_capabilities() const55198   bool has_capabilities() const { return _has_field_[1]; }
capabilities() const55199   const TracingServiceCapabilities& capabilities() const { return *capabilities_; }
mutable_capabilities()55200   TracingServiceCapabilities* mutable_capabilities() { _has_field_.set(1); return capabilities_.get(); }
55201 
55202  private:
55203   ::protozero::CopyablePtr<TracingServiceCapabilities> capabilities_;
55204 
55205   // Allows to preserve unknown protobuf fields for compatibility
55206   // with future versions of .proto files.
55207   std::string unknown_fields_;
55208 
55209   std::bitset<2> _has_field_{};
55210 };
55211 
55212 
55213 class PERFETTO_EXPORT QueryCapabilitiesRequest : public ::protozero::CppMessageObj {
55214  public:
55215   enum FieldNumbers {
55216   };
55217 
55218   QueryCapabilitiesRequest();
55219   ~QueryCapabilitiesRequest() override;
55220   QueryCapabilitiesRequest(QueryCapabilitiesRequest&&) noexcept;
55221   QueryCapabilitiesRequest& operator=(QueryCapabilitiesRequest&&);
55222   QueryCapabilitiesRequest(const QueryCapabilitiesRequest&);
55223   QueryCapabilitiesRequest& operator=(const QueryCapabilitiesRequest&);
55224   bool operator==(const QueryCapabilitiesRequest&) const;
operator !=(const QueryCapabilitiesRequest & other) const55225   bool operator!=(const QueryCapabilitiesRequest& other) const { return !(*this == other); }
55226 
55227   bool ParseFromArray(const void*, size_t) override;
55228   std::string SerializeAsString() const override;
55229   std::vector<uint8_t> SerializeAsArray() const override;
55230   void Serialize(::protozero::Message*) const;
55231 
55232  private:
55233 
55234   // Allows to preserve unknown protobuf fields for compatibility
55235   // with future versions of .proto files.
55236   std::string unknown_fields_;
55237 
55238   std::bitset<2> _has_field_{};
55239 };
55240 
55241 
55242 class PERFETTO_EXPORT QueryServiceStateResponse : public ::protozero::CppMessageObj {
55243  public:
55244   enum FieldNumbers {
55245     kServiceStateFieldNumber = 1,
55246   };
55247 
55248   QueryServiceStateResponse();
55249   ~QueryServiceStateResponse() override;
55250   QueryServiceStateResponse(QueryServiceStateResponse&&) noexcept;
55251   QueryServiceStateResponse& operator=(QueryServiceStateResponse&&);
55252   QueryServiceStateResponse(const QueryServiceStateResponse&);
55253   QueryServiceStateResponse& operator=(const QueryServiceStateResponse&);
55254   bool operator==(const QueryServiceStateResponse&) const;
operator !=(const QueryServiceStateResponse & other) const55255   bool operator!=(const QueryServiceStateResponse& other) const { return !(*this == other); }
55256 
55257   bool ParseFromArray(const void*, size_t) override;
55258   std::string SerializeAsString() const override;
55259   std::vector<uint8_t> SerializeAsArray() const override;
55260   void Serialize(::protozero::Message*) const;
55261 
has_service_state() const55262   bool has_service_state() const { return _has_field_[1]; }
service_state() const55263   const TracingServiceState& service_state() const { return *service_state_; }
mutable_service_state()55264   TracingServiceState* mutable_service_state() { _has_field_.set(1); return service_state_.get(); }
55265 
55266  private:
55267   ::protozero::CopyablePtr<TracingServiceState> service_state_;
55268 
55269   // Allows to preserve unknown protobuf fields for compatibility
55270   // with future versions of .proto files.
55271   std::string unknown_fields_;
55272 
55273   std::bitset<2> _has_field_{};
55274 };
55275 
55276 
55277 class PERFETTO_EXPORT QueryServiceStateRequest : public ::protozero::CppMessageObj {
55278  public:
55279   enum FieldNumbers {
55280   };
55281 
55282   QueryServiceStateRequest();
55283   ~QueryServiceStateRequest() override;
55284   QueryServiceStateRequest(QueryServiceStateRequest&&) noexcept;
55285   QueryServiceStateRequest& operator=(QueryServiceStateRequest&&);
55286   QueryServiceStateRequest(const QueryServiceStateRequest&);
55287   QueryServiceStateRequest& operator=(const QueryServiceStateRequest&);
55288   bool operator==(const QueryServiceStateRequest&) const;
operator !=(const QueryServiceStateRequest & other) const55289   bool operator!=(const QueryServiceStateRequest& other) const { return !(*this == other); }
55290 
55291   bool ParseFromArray(const void*, size_t) override;
55292   std::string SerializeAsString() const override;
55293   std::vector<uint8_t> SerializeAsArray() const override;
55294   void Serialize(::protozero::Message*) const;
55295 
55296  private:
55297 
55298   // Allows to preserve unknown protobuf fields for compatibility
55299   // with future versions of .proto files.
55300   std::string unknown_fields_;
55301 
55302   std::bitset<2> _has_field_{};
55303 };
55304 
55305 
55306 class PERFETTO_EXPORT ObserveEventsResponse : public ::protozero::CppMessageObj {
55307  public:
55308   enum FieldNumbers {
55309     kEventsFieldNumber = 1,
55310   };
55311 
55312   ObserveEventsResponse();
55313   ~ObserveEventsResponse() override;
55314   ObserveEventsResponse(ObserveEventsResponse&&) noexcept;
55315   ObserveEventsResponse& operator=(ObserveEventsResponse&&);
55316   ObserveEventsResponse(const ObserveEventsResponse&);
55317   ObserveEventsResponse& operator=(const ObserveEventsResponse&);
55318   bool operator==(const ObserveEventsResponse&) const;
operator !=(const ObserveEventsResponse & other) const55319   bool operator!=(const ObserveEventsResponse& other) const { return !(*this == other); }
55320 
55321   bool ParseFromArray(const void*, size_t) override;
55322   std::string SerializeAsString() const override;
55323   std::vector<uint8_t> SerializeAsArray() const override;
55324   void Serialize(::protozero::Message*) const;
55325 
has_events() const55326   bool has_events() const { return _has_field_[1]; }
events() const55327   const ObservableEvents& events() const { return *events_; }
mutable_events()55328   ObservableEvents* mutable_events() { _has_field_.set(1); return events_.get(); }
55329 
55330  private:
55331   ::protozero::CopyablePtr<ObservableEvents> events_;
55332 
55333   // Allows to preserve unknown protobuf fields for compatibility
55334   // with future versions of .proto files.
55335   std::string unknown_fields_;
55336 
55337   std::bitset<2> _has_field_{};
55338 };
55339 
55340 
55341 class PERFETTO_EXPORT ObserveEventsRequest : public ::protozero::CppMessageObj {
55342  public:
55343   enum FieldNumbers {
55344     kEventsToObserveFieldNumber = 1,
55345   };
55346 
55347   ObserveEventsRequest();
55348   ~ObserveEventsRequest() override;
55349   ObserveEventsRequest(ObserveEventsRequest&&) noexcept;
55350   ObserveEventsRequest& operator=(ObserveEventsRequest&&);
55351   ObserveEventsRequest(const ObserveEventsRequest&);
55352   ObserveEventsRequest& operator=(const ObserveEventsRequest&);
55353   bool operator==(const ObserveEventsRequest&) const;
operator !=(const ObserveEventsRequest & other) const55354   bool operator!=(const ObserveEventsRequest& other) const { return !(*this == other); }
55355 
55356   bool ParseFromArray(const void*, size_t) override;
55357   std::string SerializeAsString() const override;
55358   std::vector<uint8_t> SerializeAsArray() const override;
55359   void Serialize(::protozero::Message*) const;
55360 
events_to_observe() const55361   const std::vector<ObservableEvents_Type>& events_to_observe() const { return events_to_observe_; }
mutable_events_to_observe()55362   std::vector<ObservableEvents_Type>* mutable_events_to_observe() { return &events_to_observe_; }
events_to_observe_size() const55363   int events_to_observe_size() const { return static_cast<int>(events_to_observe_.size()); }
clear_events_to_observe()55364   void clear_events_to_observe() { events_to_observe_.clear(); }
add_events_to_observe(ObservableEvents_Type value)55365   void add_events_to_observe(ObservableEvents_Type value) { events_to_observe_.emplace_back(value); }
add_events_to_observe()55366   ObservableEvents_Type* add_events_to_observe() { events_to_observe_.emplace_back(); return &events_to_observe_.back(); }
55367 
55368  private:
55369   std::vector<ObservableEvents_Type> events_to_observe_;
55370 
55371   // Allows to preserve unknown protobuf fields for compatibility
55372   // with future versions of .proto files.
55373   std::string unknown_fields_;
55374 
55375   std::bitset<2> _has_field_{};
55376 };
55377 
55378 
55379 class PERFETTO_EXPORT GetTraceStatsResponse : public ::protozero::CppMessageObj {
55380  public:
55381   enum FieldNumbers {
55382     kTraceStatsFieldNumber = 1,
55383   };
55384 
55385   GetTraceStatsResponse();
55386   ~GetTraceStatsResponse() override;
55387   GetTraceStatsResponse(GetTraceStatsResponse&&) noexcept;
55388   GetTraceStatsResponse& operator=(GetTraceStatsResponse&&);
55389   GetTraceStatsResponse(const GetTraceStatsResponse&);
55390   GetTraceStatsResponse& operator=(const GetTraceStatsResponse&);
55391   bool operator==(const GetTraceStatsResponse&) const;
operator !=(const GetTraceStatsResponse & other) const55392   bool operator!=(const GetTraceStatsResponse& other) const { return !(*this == other); }
55393 
55394   bool ParseFromArray(const void*, size_t) override;
55395   std::string SerializeAsString() const override;
55396   std::vector<uint8_t> SerializeAsArray() const override;
55397   void Serialize(::protozero::Message*) const;
55398 
has_trace_stats() const55399   bool has_trace_stats() const { return _has_field_[1]; }
trace_stats() const55400   const TraceStats& trace_stats() const { return *trace_stats_; }
mutable_trace_stats()55401   TraceStats* mutable_trace_stats() { _has_field_.set(1); return trace_stats_.get(); }
55402 
55403  private:
55404   ::protozero::CopyablePtr<TraceStats> trace_stats_;
55405 
55406   // Allows to preserve unknown protobuf fields for compatibility
55407   // with future versions of .proto files.
55408   std::string unknown_fields_;
55409 
55410   std::bitset<2> _has_field_{};
55411 };
55412 
55413 
55414 class PERFETTO_EXPORT GetTraceStatsRequest : public ::protozero::CppMessageObj {
55415  public:
55416   enum FieldNumbers {
55417   };
55418 
55419   GetTraceStatsRequest();
55420   ~GetTraceStatsRequest() override;
55421   GetTraceStatsRequest(GetTraceStatsRequest&&) noexcept;
55422   GetTraceStatsRequest& operator=(GetTraceStatsRequest&&);
55423   GetTraceStatsRequest(const GetTraceStatsRequest&);
55424   GetTraceStatsRequest& operator=(const GetTraceStatsRequest&);
55425   bool operator==(const GetTraceStatsRequest&) const;
operator !=(const GetTraceStatsRequest & other) const55426   bool operator!=(const GetTraceStatsRequest& other) const { return !(*this == other); }
55427 
55428   bool ParseFromArray(const void*, size_t) override;
55429   std::string SerializeAsString() const override;
55430   std::vector<uint8_t> SerializeAsArray() const override;
55431   void Serialize(::protozero::Message*) const;
55432 
55433  private:
55434 
55435   // Allows to preserve unknown protobuf fields for compatibility
55436   // with future versions of .proto files.
55437   std::string unknown_fields_;
55438 
55439   std::bitset<2> _has_field_{};
55440 };
55441 
55442 
55443 class PERFETTO_EXPORT AttachResponse : public ::protozero::CppMessageObj {
55444  public:
55445   enum FieldNumbers {
55446     kTraceConfigFieldNumber = 1,
55447   };
55448 
55449   AttachResponse();
55450   ~AttachResponse() override;
55451   AttachResponse(AttachResponse&&) noexcept;
55452   AttachResponse& operator=(AttachResponse&&);
55453   AttachResponse(const AttachResponse&);
55454   AttachResponse& operator=(const AttachResponse&);
55455   bool operator==(const AttachResponse&) const;
operator !=(const AttachResponse & other) const55456   bool operator!=(const AttachResponse& other) const { return !(*this == other); }
55457 
55458   bool ParseFromArray(const void*, size_t) override;
55459   std::string SerializeAsString() const override;
55460   std::vector<uint8_t> SerializeAsArray() const override;
55461   void Serialize(::protozero::Message*) const;
55462 
has_trace_config() const55463   bool has_trace_config() const { return _has_field_[1]; }
trace_config() const55464   const TraceConfig& trace_config() const { return *trace_config_; }
mutable_trace_config()55465   TraceConfig* mutable_trace_config() { _has_field_.set(1); return trace_config_.get(); }
55466 
55467  private:
55468   ::protozero::CopyablePtr<TraceConfig> trace_config_;
55469 
55470   // Allows to preserve unknown protobuf fields for compatibility
55471   // with future versions of .proto files.
55472   std::string unknown_fields_;
55473 
55474   std::bitset<2> _has_field_{};
55475 };
55476 
55477 
55478 class PERFETTO_EXPORT AttachRequest : public ::protozero::CppMessageObj {
55479  public:
55480   enum FieldNumbers {
55481     kKeyFieldNumber = 1,
55482   };
55483 
55484   AttachRequest();
55485   ~AttachRequest() override;
55486   AttachRequest(AttachRequest&&) noexcept;
55487   AttachRequest& operator=(AttachRequest&&);
55488   AttachRequest(const AttachRequest&);
55489   AttachRequest& operator=(const AttachRequest&);
55490   bool operator==(const AttachRequest&) const;
operator !=(const AttachRequest & other) const55491   bool operator!=(const AttachRequest& other) const { return !(*this == other); }
55492 
55493   bool ParseFromArray(const void*, size_t) override;
55494   std::string SerializeAsString() const override;
55495   std::vector<uint8_t> SerializeAsArray() const override;
55496   void Serialize(::protozero::Message*) const;
55497 
has_key() const55498   bool has_key() const { return _has_field_[1]; }
key() const55499   const std::string& key() const { return key_; }
set_key(const std::string & value)55500   void set_key(const std::string& value) { key_ = value; _has_field_.set(1); }
55501 
55502  private:
55503   std::string key_{};
55504 
55505   // Allows to preserve unknown protobuf fields for compatibility
55506   // with future versions of .proto files.
55507   std::string unknown_fields_;
55508 
55509   std::bitset<2> _has_field_{};
55510 };
55511 
55512 
55513 class PERFETTO_EXPORT DetachResponse : public ::protozero::CppMessageObj {
55514  public:
55515   enum FieldNumbers {
55516   };
55517 
55518   DetachResponse();
55519   ~DetachResponse() override;
55520   DetachResponse(DetachResponse&&) noexcept;
55521   DetachResponse& operator=(DetachResponse&&);
55522   DetachResponse(const DetachResponse&);
55523   DetachResponse& operator=(const DetachResponse&);
55524   bool operator==(const DetachResponse&) const;
operator !=(const DetachResponse & other) const55525   bool operator!=(const DetachResponse& other) const { return !(*this == other); }
55526 
55527   bool ParseFromArray(const void*, size_t) override;
55528   std::string SerializeAsString() const override;
55529   std::vector<uint8_t> SerializeAsArray() const override;
55530   void Serialize(::protozero::Message*) const;
55531 
55532  private:
55533 
55534   // Allows to preserve unknown protobuf fields for compatibility
55535   // with future versions of .proto files.
55536   std::string unknown_fields_;
55537 
55538   std::bitset<2> _has_field_{};
55539 };
55540 
55541 
55542 class PERFETTO_EXPORT DetachRequest : public ::protozero::CppMessageObj {
55543  public:
55544   enum FieldNumbers {
55545     kKeyFieldNumber = 1,
55546   };
55547 
55548   DetachRequest();
55549   ~DetachRequest() override;
55550   DetachRequest(DetachRequest&&) noexcept;
55551   DetachRequest& operator=(DetachRequest&&);
55552   DetachRequest(const DetachRequest&);
55553   DetachRequest& operator=(const DetachRequest&);
55554   bool operator==(const DetachRequest&) const;
operator !=(const DetachRequest & other) const55555   bool operator!=(const DetachRequest& other) const { return !(*this == other); }
55556 
55557   bool ParseFromArray(const void*, size_t) override;
55558   std::string SerializeAsString() const override;
55559   std::vector<uint8_t> SerializeAsArray() const override;
55560   void Serialize(::protozero::Message*) const;
55561 
has_key() const55562   bool has_key() const { return _has_field_[1]; }
key() const55563   const std::string& key() const { return key_; }
set_key(const std::string & value)55564   void set_key(const std::string& value) { key_ = value; _has_field_.set(1); }
55565 
55566  private:
55567   std::string key_{};
55568 
55569   // Allows to preserve unknown protobuf fields for compatibility
55570   // with future versions of .proto files.
55571   std::string unknown_fields_;
55572 
55573   std::bitset<2> _has_field_{};
55574 };
55575 
55576 
55577 class PERFETTO_EXPORT FlushResponse : public ::protozero::CppMessageObj {
55578  public:
55579   enum FieldNumbers {
55580   };
55581 
55582   FlushResponse();
55583   ~FlushResponse() override;
55584   FlushResponse(FlushResponse&&) noexcept;
55585   FlushResponse& operator=(FlushResponse&&);
55586   FlushResponse(const FlushResponse&);
55587   FlushResponse& operator=(const FlushResponse&);
55588   bool operator==(const FlushResponse&) const;
operator !=(const FlushResponse & other) const55589   bool operator!=(const FlushResponse& other) const { return !(*this == other); }
55590 
55591   bool ParseFromArray(const void*, size_t) override;
55592   std::string SerializeAsString() const override;
55593   std::vector<uint8_t> SerializeAsArray() const override;
55594   void Serialize(::protozero::Message*) const;
55595 
55596  private:
55597 
55598   // Allows to preserve unknown protobuf fields for compatibility
55599   // with future versions of .proto files.
55600   std::string unknown_fields_;
55601 
55602   std::bitset<2> _has_field_{};
55603 };
55604 
55605 
55606 class PERFETTO_EXPORT FlushRequest : public ::protozero::CppMessageObj {
55607  public:
55608   enum FieldNumbers {
55609     kTimeoutMsFieldNumber = 1,
55610   };
55611 
55612   FlushRequest();
55613   ~FlushRequest() override;
55614   FlushRequest(FlushRequest&&) noexcept;
55615   FlushRequest& operator=(FlushRequest&&);
55616   FlushRequest(const FlushRequest&);
55617   FlushRequest& operator=(const FlushRequest&);
55618   bool operator==(const FlushRequest&) const;
operator !=(const FlushRequest & other) const55619   bool operator!=(const FlushRequest& other) const { return !(*this == other); }
55620 
55621   bool ParseFromArray(const void*, size_t) override;
55622   std::string SerializeAsString() const override;
55623   std::vector<uint8_t> SerializeAsArray() const override;
55624   void Serialize(::protozero::Message*) const;
55625 
has_timeout_ms() const55626   bool has_timeout_ms() const { return _has_field_[1]; }
timeout_ms() const55627   uint32_t timeout_ms() const { return timeout_ms_; }
set_timeout_ms(uint32_t value)55628   void set_timeout_ms(uint32_t value) { timeout_ms_ = value; _has_field_.set(1); }
55629 
55630  private:
55631   uint32_t timeout_ms_{};
55632 
55633   // Allows to preserve unknown protobuf fields for compatibility
55634   // with future versions of .proto files.
55635   std::string unknown_fields_;
55636 
55637   std::bitset<2> _has_field_{};
55638 };
55639 
55640 
55641 class PERFETTO_EXPORT FreeBuffersResponse : public ::protozero::CppMessageObj {
55642  public:
55643   enum FieldNumbers {
55644   };
55645 
55646   FreeBuffersResponse();
55647   ~FreeBuffersResponse() override;
55648   FreeBuffersResponse(FreeBuffersResponse&&) noexcept;
55649   FreeBuffersResponse& operator=(FreeBuffersResponse&&);
55650   FreeBuffersResponse(const FreeBuffersResponse&);
55651   FreeBuffersResponse& operator=(const FreeBuffersResponse&);
55652   bool operator==(const FreeBuffersResponse&) const;
operator !=(const FreeBuffersResponse & other) const55653   bool operator!=(const FreeBuffersResponse& other) const { return !(*this == other); }
55654 
55655   bool ParseFromArray(const void*, size_t) override;
55656   std::string SerializeAsString() const override;
55657   std::vector<uint8_t> SerializeAsArray() const override;
55658   void Serialize(::protozero::Message*) const;
55659 
55660  private:
55661 
55662   // Allows to preserve unknown protobuf fields for compatibility
55663   // with future versions of .proto files.
55664   std::string unknown_fields_;
55665 
55666   std::bitset<2> _has_field_{};
55667 };
55668 
55669 
55670 class PERFETTO_EXPORT FreeBuffersRequest : public ::protozero::CppMessageObj {
55671  public:
55672   enum FieldNumbers {
55673     kBufferIdsFieldNumber = 1,
55674   };
55675 
55676   FreeBuffersRequest();
55677   ~FreeBuffersRequest() override;
55678   FreeBuffersRequest(FreeBuffersRequest&&) noexcept;
55679   FreeBuffersRequest& operator=(FreeBuffersRequest&&);
55680   FreeBuffersRequest(const FreeBuffersRequest&);
55681   FreeBuffersRequest& operator=(const FreeBuffersRequest&);
55682   bool operator==(const FreeBuffersRequest&) const;
operator !=(const FreeBuffersRequest & other) const55683   bool operator!=(const FreeBuffersRequest& other) const { return !(*this == other); }
55684 
55685   bool ParseFromArray(const void*, size_t) override;
55686   std::string SerializeAsString() const override;
55687   std::vector<uint8_t> SerializeAsArray() const override;
55688   void Serialize(::protozero::Message*) const;
55689 
buffer_ids() const55690   const std::vector<uint32_t>& buffer_ids() const { return buffer_ids_; }
mutable_buffer_ids()55691   std::vector<uint32_t>* mutable_buffer_ids() { return &buffer_ids_; }
buffer_ids_size() const55692   int buffer_ids_size() const { return static_cast<int>(buffer_ids_.size()); }
clear_buffer_ids()55693   void clear_buffer_ids() { buffer_ids_.clear(); }
add_buffer_ids(uint32_t value)55694   void add_buffer_ids(uint32_t value) { buffer_ids_.emplace_back(value); }
add_buffer_ids()55695   uint32_t* add_buffer_ids() { buffer_ids_.emplace_back(); return &buffer_ids_.back(); }
55696 
55697  private:
55698   std::vector<uint32_t> buffer_ids_;
55699 
55700   // Allows to preserve unknown protobuf fields for compatibility
55701   // with future versions of .proto files.
55702   std::string unknown_fields_;
55703 
55704   std::bitset<2> _has_field_{};
55705 };
55706 
55707 
55708 class PERFETTO_EXPORT ReadBuffersResponse : public ::protozero::CppMessageObj {
55709  public:
55710   using Slice = ReadBuffersResponse_Slice;
55711   enum FieldNumbers {
55712     kSlicesFieldNumber = 2,
55713   };
55714 
55715   ReadBuffersResponse();
55716   ~ReadBuffersResponse() override;
55717   ReadBuffersResponse(ReadBuffersResponse&&) noexcept;
55718   ReadBuffersResponse& operator=(ReadBuffersResponse&&);
55719   ReadBuffersResponse(const ReadBuffersResponse&);
55720   ReadBuffersResponse& operator=(const ReadBuffersResponse&);
55721   bool operator==(const ReadBuffersResponse&) const;
operator !=(const ReadBuffersResponse & other) const55722   bool operator!=(const ReadBuffersResponse& other) const { return !(*this == other); }
55723 
55724   bool ParseFromArray(const void*, size_t) override;
55725   std::string SerializeAsString() const override;
55726   std::vector<uint8_t> SerializeAsArray() const override;
55727   void Serialize(::protozero::Message*) const;
55728 
slices() const55729   const std::vector<ReadBuffersResponse_Slice>& slices() const { return slices_; }
mutable_slices()55730   std::vector<ReadBuffersResponse_Slice>* mutable_slices() { return &slices_; }
55731   int slices_size() const;
55732   void clear_slices();
55733   ReadBuffersResponse_Slice* add_slices();
55734 
55735  private:
55736   std::vector<ReadBuffersResponse_Slice> slices_;
55737 
55738   // Allows to preserve unknown protobuf fields for compatibility
55739   // with future versions of .proto files.
55740   std::string unknown_fields_;
55741 
55742   std::bitset<3> _has_field_{};
55743 };
55744 
55745 
55746 class PERFETTO_EXPORT ReadBuffersResponse_Slice : public ::protozero::CppMessageObj {
55747  public:
55748   enum FieldNumbers {
55749     kDataFieldNumber = 1,
55750     kLastSliceForPacketFieldNumber = 2,
55751   };
55752 
55753   ReadBuffersResponse_Slice();
55754   ~ReadBuffersResponse_Slice() override;
55755   ReadBuffersResponse_Slice(ReadBuffersResponse_Slice&&) noexcept;
55756   ReadBuffersResponse_Slice& operator=(ReadBuffersResponse_Slice&&);
55757   ReadBuffersResponse_Slice(const ReadBuffersResponse_Slice&);
55758   ReadBuffersResponse_Slice& operator=(const ReadBuffersResponse_Slice&);
55759   bool operator==(const ReadBuffersResponse_Slice&) const;
operator !=(const ReadBuffersResponse_Slice & other) const55760   bool operator!=(const ReadBuffersResponse_Slice& other) const { return !(*this == other); }
55761 
55762   bool ParseFromArray(const void*, size_t) override;
55763   std::string SerializeAsString() const override;
55764   std::vector<uint8_t> SerializeAsArray() const override;
55765   void Serialize(::protozero::Message*) const;
55766 
has_data() const55767   bool has_data() const { return _has_field_[1]; }
data() const55768   const std::string& data() const { return data_; }
set_data(const std::string & value)55769   void set_data(const std::string& value) { data_ = value; _has_field_.set(1); }
set_data(const void * p,size_t s)55770   void set_data(const void* p, size_t s) { data_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(1); }
55771 
has_last_slice_for_packet() const55772   bool has_last_slice_for_packet() const { return _has_field_[2]; }
last_slice_for_packet() const55773   bool last_slice_for_packet() const { return last_slice_for_packet_; }
set_last_slice_for_packet(bool value)55774   void set_last_slice_for_packet(bool value) { last_slice_for_packet_ = value; _has_field_.set(2); }
55775 
55776  private:
55777   std::string data_{};
55778   bool last_slice_for_packet_{};
55779 
55780   // Allows to preserve unknown protobuf fields for compatibility
55781   // with future versions of .proto files.
55782   std::string unknown_fields_;
55783 
55784   std::bitset<3> _has_field_{};
55785 };
55786 
55787 
55788 class PERFETTO_EXPORT ReadBuffersRequest : public ::protozero::CppMessageObj {
55789  public:
55790   enum FieldNumbers {
55791   };
55792 
55793   ReadBuffersRequest();
55794   ~ReadBuffersRequest() override;
55795   ReadBuffersRequest(ReadBuffersRequest&&) noexcept;
55796   ReadBuffersRequest& operator=(ReadBuffersRequest&&);
55797   ReadBuffersRequest(const ReadBuffersRequest&);
55798   ReadBuffersRequest& operator=(const ReadBuffersRequest&);
55799   bool operator==(const ReadBuffersRequest&) const;
operator !=(const ReadBuffersRequest & other) const55800   bool operator!=(const ReadBuffersRequest& other) const { return !(*this == other); }
55801 
55802   bool ParseFromArray(const void*, size_t) override;
55803   std::string SerializeAsString() const override;
55804   std::vector<uint8_t> SerializeAsArray() const override;
55805   void Serialize(::protozero::Message*) const;
55806 
55807  private:
55808 
55809   // Allows to preserve unknown protobuf fields for compatibility
55810   // with future versions of .proto files.
55811   std::string unknown_fields_;
55812 
55813   std::bitset<2> _has_field_{};
55814 };
55815 
55816 
55817 class PERFETTO_EXPORT DisableTracingResponse : public ::protozero::CppMessageObj {
55818  public:
55819   enum FieldNumbers {
55820   };
55821 
55822   DisableTracingResponse();
55823   ~DisableTracingResponse() override;
55824   DisableTracingResponse(DisableTracingResponse&&) noexcept;
55825   DisableTracingResponse& operator=(DisableTracingResponse&&);
55826   DisableTracingResponse(const DisableTracingResponse&);
55827   DisableTracingResponse& operator=(const DisableTracingResponse&);
55828   bool operator==(const DisableTracingResponse&) const;
operator !=(const DisableTracingResponse & other) const55829   bool operator!=(const DisableTracingResponse& other) const { return !(*this == other); }
55830 
55831   bool ParseFromArray(const void*, size_t) override;
55832   std::string SerializeAsString() const override;
55833   std::vector<uint8_t> SerializeAsArray() const override;
55834   void Serialize(::protozero::Message*) const;
55835 
55836  private:
55837 
55838   // Allows to preserve unknown protobuf fields for compatibility
55839   // with future versions of .proto files.
55840   std::string unknown_fields_;
55841 
55842   std::bitset<2> _has_field_{};
55843 };
55844 
55845 
55846 class PERFETTO_EXPORT DisableTracingRequest : public ::protozero::CppMessageObj {
55847  public:
55848   enum FieldNumbers {
55849   };
55850 
55851   DisableTracingRequest();
55852   ~DisableTracingRequest() override;
55853   DisableTracingRequest(DisableTracingRequest&&) noexcept;
55854   DisableTracingRequest& operator=(DisableTracingRequest&&);
55855   DisableTracingRequest(const DisableTracingRequest&);
55856   DisableTracingRequest& operator=(const DisableTracingRequest&);
55857   bool operator==(const DisableTracingRequest&) const;
operator !=(const DisableTracingRequest & other) const55858   bool operator!=(const DisableTracingRequest& other) const { return !(*this == other); }
55859 
55860   bool ParseFromArray(const void*, size_t) override;
55861   std::string SerializeAsString() const override;
55862   std::vector<uint8_t> SerializeAsArray() const override;
55863   void Serialize(::protozero::Message*) const;
55864 
55865  private:
55866 
55867   // Allows to preserve unknown protobuf fields for compatibility
55868   // with future versions of .proto files.
55869   std::string unknown_fields_;
55870 
55871   std::bitset<2> _has_field_{};
55872 };
55873 
55874 
55875 class PERFETTO_EXPORT ChangeTraceConfigResponse : public ::protozero::CppMessageObj {
55876  public:
55877   enum FieldNumbers {
55878   };
55879 
55880   ChangeTraceConfigResponse();
55881   ~ChangeTraceConfigResponse() override;
55882   ChangeTraceConfigResponse(ChangeTraceConfigResponse&&) noexcept;
55883   ChangeTraceConfigResponse& operator=(ChangeTraceConfigResponse&&);
55884   ChangeTraceConfigResponse(const ChangeTraceConfigResponse&);
55885   ChangeTraceConfigResponse& operator=(const ChangeTraceConfigResponse&);
55886   bool operator==(const ChangeTraceConfigResponse&) const;
operator !=(const ChangeTraceConfigResponse & other) const55887   bool operator!=(const ChangeTraceConfigResponse& other) const { return !(*this == other); }
55888 
55889   bool ParseFromArray(const void*, size_t) override;
55890   std::string SerializeAsString() const override;
55891   std::vector<uint8_t> SerializeAsArray() const override;
55892   void Serialize(::protozero::Message*) const;
55893 
55894  private:
55895 
55896   // Allows to preserve unknown protobuf fields for compatibility
55897   // with future versions of .proto files.
55898   std::string unknown_fields_;
55899 
55900   std::bitset<2> _has_field_{};
55901 };
55902 
55903 
55904 class PERFETTO_EXPORT ChangeTraceConfigRequest : public ::protozero::CppMessageObj {
55905  public:
55906   enum FieldNumbers {
55907     kTraceConfigFieldNumber = 1,
55908   };
55909 
55910   ChangeTraceConfigRequest();
55911   ~ChangeTraceConfigRequest() override;
55912   ChangeTraceConfigRequest(ChangeTraceConfigRequest&&) noexcept;
55913   ChangeTraceConfigRequest& operator=(ChangeTraceConfigRequest&&);
55914   ChangeTraceConfigRequest(const ChangeTraceConfigRequest&);
55915   ChangeTraceConfigRequest& operator=(const ChangeTraceConfigRequest&);
55916   bool operator==(const ChangeTraceConfigRequest&) const;
operator !=(const ChangeTraceConfigRequest & other) const55917   bool operator!=(const ChangeTraceConfigRequest& other) const { return !(*this == other); }
55918 
55919   bool ParseFromArray(const void*, size_t) override;
55920   std::string SerializeAsString() const override;
55921   std::vector<uint8_t> SerializeAsArray() const override;
55922   void Serialize(::protozero::Message*) const;
55923 
has_trace_config() const55924   bool has_trace_config() const { return _has_field_[1]; }
trace_config() const55925   const TraceConfig& trace_config() const { return *trace_config_; }
mutable_trace_config()55926   TraceConfig* mutable_trace_config() { _has_field_.set(1); return trace_config_.get(); }
55927 
55928  private:
55929   ::protozero::CopyablePtr<TraceConfig> trace_config_;
55930 
55931   // Allows to preserve unknown protobuf fields for compatibility
55932   // with future versions of .proto files.
55933   std::string unknown_fields_;
55934 
55935   std::bitset<2> _has_field_{};
55936 };
55937 
55938 
55939 class PERFETTO_EXPORT StartTracingResponse : public ::protozero::CppMessageObj {
55940  public:
55941   enum FieldNumbers {
55942   };
55943 
55944   StartTracingResponse();
55945   ~StartTracingResponse() override;
55946   StartTracingResponse(StartTracingResponse&&) noexcept;
55947   StartTracingResponse& operator=(StartTracingResponse&&);
55948   StartTracingResponse(const StartTracingResponse&);
55949   StartTracingResponse& operator=(const StartTracingResponse&);
55950   bool operator==(const StartTracingResponse&) const;
operator !=(const StartTracingResponse & other) const55951   bool operator!=(const StartTracingResponse& other) const { return !(*this == other); }
55952 
55953   bool ParseFromArray(const void*, size_t) override;
55954   std::string SerializeAsString() const override;
55955   std::vector<uint8_t> SerializeAsArray() const override;
55956   void Serialize(::protozero::Message*) const;
55957 
55958  private:
55959 
55960   // Allows to preserve unknown protobuf fields for compatibility
55961   // with future versions of .proto files.
55962   std::string unknown_fields_;
55963 
55964   std::bitset<2> _has_field_{};
55965 };
55966 
55967 
55968 class PERFETTO_EXPORT StartTracingRequest : public ::protozero::CppMessageObj {
55969  public:
55970   enum FieldNumbers {
55971   };
55972 
55973   StartTracingRequest();
55974   ~StartTracingRequest() override;
55975   StartTracingRequest(StartTracingRequest&&) noexcept;
55976   StartTracingRequest& operator=(StartTracingRequest&&);
55977   StartTracingRequest(const StartTracingRequest&);
55978   StartTracingRequest& operator=(const StartTracingRequest&);
55979   bool operator==(const StartTracingRequest&) const;
operator !=(const StartTracingRequest & other) const55980   bool operator!=(const StartTracingRequest& other) const { return !(*this == other); }
55981 
55982   bool ParseFromArray(const void*, size_t) override;
55983   std::string SerializeAsString() const override;
55984   std::vector<uint8_t> SerializeAsArray() const override;
55985   void Serialize(::protozero::Message*) const;
55986 
55987  private:
55988 
55989   // Allows to preserve unknown protobuf fields for compatibility
55990   // with future versions of .proto files.
55991   std::string unknown_fields_;
55992 
55993   std::bitset<2> _has_field_{};
55994 };
55995 
55996 
55997 class PERFETTO_EXPORT EnableTracingResponse : public ::protozero::CppMessageObj {
55998  public:
55999   enum FieldNumbers {
56000     kDisabledFieldNumber = 1,
56001     kErrorFieldNumber = 3,
56002   };
56003 
56004   EnableTracingResponse();
56005   ~EnableTracingResponse() override;
56006   EnableTracingResponse(EnableTracingResponse&&) noexcept;
56007   EnableTracingResponse& operator=(EnableTracingResponse&&);
56008   EnableTracingResponse(const EnableTracingResponse&);
56009   EnableTracingResponse& operator=(const EnableTracingResponse&);
56010   bool operator==(const EnableTracingResponse&) const;
operator !=(const EnableTracingResponse & other) const56011   bool operator!=(const EnableTracingResponse& other) const { return !(*this == other); }
56012 
56013   bool ParseFromArray(const void*, size_t) override;
56014   std::string SerializeAsString() const override;
56015   std::vector<uint8_t> SerializeAsArray() const override;
56016   void Serialize(::protozero::Message*) const;
56017 
has_disabled() const56018   bool has_disabled() const { return _has_field_[1]; }
disabled() const56019   bool disabled() const { return disabled_; }
set_disabled(bool value)56020   void set_disabled(bool value) { disabled_ = value; _has_field_.set(1); }
56021 
has_error() const56022   bool has_error() const { return _has_field_[3]; }
error() const56023   const std::string& error() const { return error_; }
set_error(const std::string & value)56024   void set_error(const std::string& value) { error_ = value; _has_field_.set(3); }
56025 
56026  private:
56027   bool disabled_{};
56028   std::string error_{};
56029 
56030   // Allows to preserve unknown protobuf fields for compatibility
56031   // with future versions of .proto files.
56032   std::string unknown_fields_;
56033 
56034   std::bitset<4> _has_field_{};
56035 };
56036 
56037 
56038 class PERFETTO_EXPORT EnableTracingRequest : public ::protozero::CppMessageObj {
56039  public:
56040   enum FieldNumbers {
56041     kTraceConfigFieldNumber = 1,
56042     kAttachNotificationOnlyFieldNumber = 2,
56043   };
56044 
56045   EnableTracingRequest();
56046   ~EnableTracingRequest() override;
56047   EnableTracingRequest(EnableTracingRequest&&) noexcept;
56048   EnableTracingRequest& operator=(EnableTracingRequest&&);
56049   EnableTracingRequest(const EnableTracingRequest&);
56050   EnableTracingRequest& operator=(const EnableTracingRequest&);
56051   bool operator==(const EnableTracingRequest&) const;
operator !=(const EnableTracingRequest & other) const56052   bool operator!=(const EnableTracingRequest& other) const { return !(*this == other); }
56053 
56054   bool ParseFromArray(const void*, size_t) override;
56055   std::string SerializeAsString() const override;
56056   std::vector<uint8_t> SerializeAsArray() const override;
56057   void Serialize(::protozero::Message*) const;
56058 
has_trace_config() const56059   bool has_trace_config() const { return _has_field_[1]; }
trace_config() const56060   const TraceConfig& trace_config() const { return *trace_config_; }
mutable_trace_config()56061   TraceConfig* mutable_trace_config() { _has_field_.set(1); return trace_config_.get(); }
56062 
has_attach_notification_only() const56063   bool has_attach_notification_only() const { return _has_field_[2]; }
attach_notification_only() const56064   bool attach_notification_only() const { return attach_notification_only_; }
set_attach_notification_only(bool value)56065   void set_attach_notification_only(bool value) { attach_notification_only_ = value; _has_field_.set(2); }
56066 
56067  private:
56068   ::protozero::CopyablePtr<TraceConfig> trace_config_;
56069   bool attach_notification_only_{};
56070 
56071   // Allows to preserve unknown protobuf fields for compatibility
56072   // with future versions of .proto files.
56073   std::string unknown_fields_;
56074 
56075   std::bitset<3> _has_field_{};
56076 };
56077 
56078 }  // namespace perfetto
56079 }  // namespace protos
56080 }  // namespace gen
56081 
56082 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_CONSUMER_PORT_PROTO_CPP_H_
56083 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
56084 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
56085 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
56086 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
56087 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
56088 #if defined(__GNUC__) || defined(__clang__)
56089 #pragma GCC diagnostic push
56090 #pragma GCC diagnostic ignored "-Wfloat-equal"
56091 #endif
56092 // gen_amalgamated expanded: #include "protos/perfetto/ipc/consumer_port.gen.h"
56093 // gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.gen.h"
56094 // gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"
56095 // gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
56096 // gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"
56097 // gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
56098 // gen_amalgamated expanded: #include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
56099 // gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
56100 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/perf_event_config.gen.h"
56101 // gen_amalgamated expanded: #include "protos/perfetto/common/perf_events.gen.h"
56102 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/java_hprof_config.gen.h"
56103 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/heapprofd_config.gen.h"
56104 // gen_amalgamated expanded: #include "protos/perfetto/config/process_stats/process_stats_config.gen.h"
56105 // gen_amalgamated expanded: #include "protos/perfetto/config/power/android_power_config.gen.h"
56106 // gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
56107 // gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
56108 // gen_amalgamated expanded: #include "protos/perfetto/config/inode_file/inode_file_config.gen.h"
56109 // gen_amalgamated expanded: #include "protos/perfetto/config/gpu/vulkan_memory_config.gen.h"
56110 // gen_amalgamated expanded: #include "protos/perfetto/config/gpu/gpu_counter_config.gen.h"
56111 // gen_amalgamated expanded: #include "protos/perfetto/config/ftrace/ftrace_config.gen.h"
56112 // gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
56113 // gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_config.gen.h"
56114 // gen_amalgamated expanded: #include "protos/perfetto/config/android/android_polled_state_config.gen.h"
56115 // gen_amalgamated expanded: #include "protos/perfetto/config/android/android_log_config.gen.h"
56116 // gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
56117 // gen_amalgamated expanded: #include "protos/perfetto/common/trace_stats.gen.h"
56118 // gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_capabilities.gen.h"
56119 // gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"
56120 // gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_state.gen.h"
56121 // gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
56122 // gen_amalgamated expanded: #include "protos/perfetto/common/track_event_descriptor.gen.h"
56123 // gen_amalgamated expanded: #include "protos/perfetto/common/gpu_counter_descriptor.gen.h"
56124 // gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"
56125 
56126 namespace perfetto {
56127 namespace protos {
56128 namespace gen {
56129 
56130 SaveTraceForBugreportResponse::SaveTraceForBugreportResponse() = default;
56131 SaveTraceForBugreportResponse::~SaveTraceForBugreportResponse() = default;
56132 SaveTraceForBugreportResponse::SaveTraceForBugreportResponse(const SaveTraceForBugreportResponse&) = default;
56133 SaveTraceForBugreportResponse& SaveTraceForBugreportResponse::operator=(const SaveTraceForBugreportResponse&) = default;
56134 SaveTraceForBugreportResponse::SaveTraceForBugreportResponse(SaveTraceForBugreportResponse&&) noexcept = default;
56135 SaveTraceForBugreportResponse& SaveTraceForBugreportResponse::operator=(SaveTraceForBugreportResponse&&) = default;
56136 
operator ==(const SaveTraceForBugreportResponse & other) const56137 bool SaveTraceForBugreportResponse::operator==(const SaveTraceForBugreportResponse& other) const {
56138   return unknown_fields_ == other.unknown_fields_
56139    && success_ == other.success_
56140    && msg_ == other.msg_;
56141 }
56142 
ParseFromArray(const void * raw,size_t size)56143 bool SaveTraceForBugreportResponse::ParseFromArray(const void* raw, size_t size) {
56144   unknown_fields_.clear();
56145   bool packed_error = false;
56146 
56147   ::protozero::ProtoDecoder dec(raw, size);
56148   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
56149     if (field.id() < _has_field_.size()) {
56150       _has_field_.set(field.id());
56151     }
56152     switch (field.id()) {
56153       case 1 /* success */:
56154         field.get(&success_);
56155         break;
56156       case 2 /* msg */:
56157         field.get(&msg_);
56158         break;
56159       default:
56160         field.SerializeAndAppendTo(&unknown_fields_);
56161         break;
56162     }
56163   }
56164   return !packed_error && !dec.bytes_left();
56165 }
56166 
SerializeAsString() const56167 std::string SaveTraceForBugreportResponse::SerializeAsString() const {
56168   ::protozero::HeapBuffered<::protozero::Message> msg;
56169   Serialize(msg.get());
56170   return msg.SerializeAsString();
56171 }
56172 
SerializeAsArray() const56173 std::vector<uint8_t> SaveTraceForBugreportResponse::SerializeAsArray() const {
56174   ::protozero::HeapBuffered<::protozero::Message> msg;
56175   Serialize(msg.get());
56176   return msg.SerializeAsArray();
56177 }
56178 
Serialize(::protozero::Message * msg) const56179 void SaveTraceForBugreportResponse::Serialize(::protozero::Message* msg) const {
56180   // Field 1: success
56181   if (_has_field_[1]) {
56182     msg->AppendTinyVarInt(1, success_);
56183   }
56184 
56185   // Field 2: msg
56186   if (_has_field_[2]) {
56187     msg->AppendString(2, msg_);
56188   }
56189 
56190   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
56191 }
56192 
56193 
56194 SaveTraceForBugreportRequest::SaveTraceForBugreportRequest() = default;
56195 SaveTraceForBugreportRequest::~SaveTraceForBugreportRequest() = default;
56196 SaveTraceForBugreportRequest::SaveTraceForBugreportRequest(const SaveTraceForBugreportRequest&) = default;
56197 SaveTraceForBugreportRequest& SaveTraceForBugreportRequest::operator=(const SaveTraceForBugreportRequest&) = default;
56198 SaveTraceForBugreportRequest::SaveTraceForBugreportRequest(SaveTraceForBugreportRequest&&) noexcept = default;
56199 SaveTraceForBugreportRequest& SaveTraceForBugreportRequest::operator=(SaveTraceForBugreportRequest&&) = default;
56200 
operator ==(const SaveTraceForBugreportRequest & other) const56201 bool SaveTraceForBugreportRequest::operator==(const SaveTraceForBugreportRequest& other) const {
56202   return unknown_fields_ == other.unknown_fields_;
56203 }
56204 
ParseFromArray(const void * raw,size_t size)56205 bool SaveTraceForBugreportRequest::ParseFromArray(const void* raw, size_t size) {
56206   unknown_fields_.clear();
56207   bool packed_error = false;
56208 
56209   ::protozero::ProtoDecoder dec(raw, size);
56210   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
56211     if (field.id() < _has_field_.size()) {
56212       _has_field_.set(field.id());
56213     }
56214     switch (field.id()) {
56215       default:
56216         field.SerializeAndAppendTo(&unknown_fields_);
56217         break;
56218     }
56219   }
56220   return !packed_error && !dec.bytes_left();
56221 }
56222 
SerializeAsString() const56223 std::string SaveTraceForBugreportRequest::SerializeAsString() const {
56224   ::protozero::HeapBuffered<::protozero::Message> msg;
56225   Serialize(msg.get());
56226   return msg.SerializeAsString();
56227 }
56228 
SerializeAsArray() const56229 std::vector<uint8_t> SaveTraceForBugreportRequest::SerializeAsArray() const {
56230   ::protozero::HeapBuffered<::protozero::Message> msg;
56231   Serialize(msg.get());
56232   return msg.SerializeAsArray();
56233 }
56234 
Serialize(::protozero::Message * msg) const56235 void SaveTraceForBugreportRequest::Serialize(::protozero::Message* msg) const {
56236   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
56237 }
56238 
56239 
56240 QueryCapabilitiesResponse::QueryCapabilitiesResponse() = default;
56241 QueryCapabilitiesResponse::~QueryCapabilitiesResponse() = default;
56242 QueryCapabilitiesResponse::QueryCapabilitiesResponse(const QueryCapabilitiesResponse&) = default;
56243 QueryCapabilitiesResponse& QueryCapabilitiesResponse::operator=(const QueryCapabilitiesResponse&) = default;
56244 QueryCapabilitiesResponse::QueryCapabilitiesResponse(QueryCapabilitiesResponse&&) noexcept = default;
56245 QueryCapabilitiesResponse& QueryCapabilitiesResponse::operator=(QueryCapabilitiesResponse&&) = default;
56246 
operator ==(const QueryCapabilitiesResponse & other) const56247 bool QueryCapabilitiesResponse::operator==(const QueryCapabilitiesResponse& other) const {
56248   return unknown_fields_ == other.unknown_fields_
56249    && capabilities_ == other.capabilities_;
56250 }
56251 
ParseFromArray(const void * raw,size_t size)56252 bool QueryCapabilitiesResponse::ParseFromArray(const void* raw, size_t size) {
56253   unknown_fields_.clear();
56254   bool packed_error = false;
56255 
56256   ::protozero::ProtoDecoder dec(raw, size);
56257   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
56258     if (field.id() < _has_field_.size()) {
56259       _has_field_.set(field.id());
56260     }
56261     switch (field.id()) {
56262       case 1 /* capabilities */:
56263         (*capabilities_).ParseFromArray(field.data(), field.size());
56264         break;
56265       default:
56266         field.SerializeAndAppendTo(&unknown_fields_);
56267         break;
56268     }
56269   }
56270   return !packed_error && !dec.bytes_left();
56271 }
56272 
SerializeAsString() const56273 std::string QueryCapabilitiesResponse::SerializeAsString() const {
56274   ::protozero::HeapBuffered<::protozero::Message> msg;
56275   Serialize(msg.get());
56276   return msg.SerializeAsString();
56277 }
56278 
SerializeAsArray() const56279 std::vector<uint8_t> QueryCapabilitiesResponse::SerializeAsArray() const {
56280   ::protozero::HeapBuffered<::protozero::Message> msg;
56281   Serialize(msg.get());
56282   return msg.SerializeAsArray();
56283 }
56284 
Serialize(::protozero::Message * msg) const56285 void QueryCapabilitiesResponse::Serialize(::protozero::Message* msg) const {
56286   // Field 1: capabilities
56287   if (_has_field_[1]) {
56288     (*capabilities_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
56289   }
56290 
56291   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
56292 }
56293 
56294 
56295 QueryCapabilitiesRequest::QueryCapabilitiesRequest() = default;
56296 QueryCapabilitiesRequest::~QueryCapabilitiesRequest() = default;
56297 QueryCapabilitiesRequest::QueryCapabilitiesRequest(const QueryCapabilitiesRequest&) = default;
56298 QueryCapabilitiesRequest& QueryCapabilitiesRequest::operator=(const QueryCapabilitiesRequest&) = default;
56299 QueryCapabilitiesRequest::QueryCapabilitiesRequest(QueryCapabilitiesRequest&&) noexcept = default;
56300 QueryCapabilitiesRequest& QueryCapabilitiesRequest::operator=(QueryCapabilitiesRequest&&) = default;
56301 
operator ==(const QueryCapabilitiesRequest & other) const56302 bool QueryCapabilitiesRequest::operator==(const QueryCapabilitiesRequest& other) const {
56303   return unknown_fields_ == other.unknown_fields_;
56304 }
56305 
ParseFromArray(const void * raw,size_t size)56306 bool QueryCapabilitiesRequest::ParseFromArray(const void* raw, size_t size) {
56307   unknown_fields_.clear();
56308   bool packed_error = false;
56309 
56310   ::protozero::ProtoDecoder dec(raw, size);
56311   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
56312     if (field.id() < _has_field_.size()) {
56313       _has_field_.set(field.id());
56314     }
56315     switch (field.id()) {
56316       default:
56317         field.SerializeAndAppendTo(&unknown_fields_);
56318         break;
56319     }
56320   }
56321   return !packed_error && !dec.bytes_left();
56322 }
56323 
SerializeAsString() const56324 std::string QueryCapabilitiesRequest::SerializeAsString() const {
56325   ::protozero::HeapBuffered<::protozero::Message> msg;
56326   Serialize(msg.get());
56327   return msg.SerializeAsString();
56328 }
56329 
SerializeAsArray() const56330 std::vector<uint8_t> QueryCapabilitiesRequest::SerializeAsArray() const {
56331   ::protozero::HeapBuffered<::protozero::Message> msg;
56332   Serialize(msg.get());
56333   return msg.SerializeAsArray();
56334 }
56335 
Serialize(::protozero::Message * msg) const56336 void QueryCapabilitiesRequest::Serialize(::protozero::Message* msg) const {
56337   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
56338 }
56339 
56340 
56341 QueryServiceStateResponse::QueryServiceStateResponse() = default;
56342 QueryServiceStateResponse::~QueryServiceStateResponse() = default;
56343 QueryServiceStateResponse::QueryServiceStateResponse(const QueryServiceStateResponse&) = default;
56344 QueryServiceStateResponse& QueryServiceStateResponse::operator=(const QueryServiceStateResponse&) = default;
56345 QueryServiceStateResponse::QueryServiceStateResponse(QueryServiceStateResponse&&) noexcept = default;
56346 QueryServiceStateResponse& QueryServiceStateResponse::operator=(QueryServiceStateResponse&&) = default;
56347 
operator ==(const QueryServiceStateResponse & other) const56348 bool QueryServiceStateResponse::operator==(const QueryServiceStateResponse& other) const {
56349   return unknown_fields_ == other.unknown_fields_
56350    && service_state_ == other.service_state_;
56351 }
56352 
ParseFromArray(const void * raw,size_t size)56353 bool QueryServiceStateResponse::ParseFromArray(const void* raw, size_t size) {
56354   unknown_fields_.clear();
56355   bool packed_error = false;
56356 
56357   ::protozero::ProtoDecoder dec(raw, size);
56358   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
56359     if (field.id() < _has_field_.size()) {
56360       _has_field_.set(field.id());
56361     }
56362     switch (field.id()) {
56363       case 1 /* service_state */:
56364         (*service_state_).ParseFromArray(field.data(), field.size());
56365         break;
56366       default:
56367         field.SerializeAndAppendTo(&unknown_fields_);
56368         break;
56369     }
56370   }
56371   return !packed_error && !dec.bytes_left();
56372 }
56373 
SerializeAsString() const56374 std::string QueryServiceStateResponse::SerializeAsString() const {
56375   ::protozero::HeapBuffered<::protozero::Message> msg;
56376   Serialize(msg.get());
56377   return msg.SerializeAsString();
56378 }
56379 
SerializeAsArray() const56380 std::vector<uint8_t> QueryServiceStateResponse::SerializeAsArray() const {
56381   ::protozero::HeapBuffered<::protozero::Message> msg;
56382   Serialize(msg.get());
56383   return msg.SerializeAsArray();
56384 }
56385 
Serialize(::protozero::Message * msg) const56386 void QueryServiceStateResponse::Serialize(::protozero::Message* msg) const {
56387   // Field 1: service_state
56388   if (_has_field_[1]) {
56389     (*service_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
56390   }
56391 
56392   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
56393 }
56394 
56395 
56396 QueryServiceStateRequest::QueryServiceStateRequest() = default;
56397 QueryServiceStateRequest::~QueryServiceStateRequest() = default;
56398 QueryServiceStateRequest::QueryServiceStateRequest(const QueryServiceStateRequest&) = default;
56399 QueryServiceStateRequest& QueryServiceStateRequest::operator=(const QueryServiceStateRequest&) = default;
56400 QueryServiceStateRequest::QueryServiceStateRequest(QueryServiceStateRequest&&) noexcept = default;
56401 QueryServiceStateRequest& QueryServiceStateRequest::operator=(QueryServiceStateRequest&&) = default;
56402 
operator ==(const QueryServiceStateRequest & other) const56403 bool QueryServiceStateRequest::operator==(const QueryServiceStateRequest& other) const {
56404   return unknown_fields_ == other.unknown_fields_;
56405 }
56406 
ParseFromArray(const void * raw,size_t size)56407 bool QueryServiceStateRequest::ParseFromArray(const void* raw, size_t size) {
56408   unknown_fields_.clear();
56409   bool packed_error = false;
56410 
56411   ::protozero::ProtoDecoder dec(raw, size);
56412   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
56413     if (field.id() < _has_field_.size()) {
56414       _has_field_.set(field.id());
56415     }
56416     switch (field.id()) {
56417       default:
56418         field.SerializeAndAppendTo(&unknown_fields_);
56419         break;
56420     }
56421   }
56422   return !packed_error && !dec.bytes_left();
56423 }
56424 
SerializeAsString() const56425 std::string QueryServiceStateRequest::SerializeAsString() const {
56426   ::protozero::HeapBuffered<::protozero::Message> msg;
56427   Serialize(msg.get());
56428   return msg.SerializeAsString();
56429 }
56430 
SerializeAsArray() const56431 std::vector<uint8_t> QueryServiceStateRequest::SerializeAsArray() const {
56432   ::protozero::HeapBuffered<::protozero::Message> msg;
56433   Serialize(msg.get());
56434   return msg.SerializeAsArray();
56435 }
56436 
Serialize(::protozero::Message * msg) const56437 void QueryServiceStateRequest::Serialize(::protozero::Message* msg) const {
56438   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
56439 }
56440 
56441 
56442 ObserveEventsResponse::ObserveEventsResponse() = default;
56443 ObserveEventsResponse::~ObserveEventsResponse() = default;
56444 ObserveEventsResponse::ObserveEventsResponse(const ObserveEventsResponse&) = default;
56445 ObserveEventsResponse& ObserveEventsResponse::operator=(const ObserveEventsResponse&) = default;
56446 ObserveEventsResponse::ObserveEventsResponse(ObserveEventsResponse&&) noexcept = default;
56447 ObserveEventsResponse& ObserveEventsResponse::operator=(ObserveEventsResponse&&) = default;
56448 
operator ==(const ObserveEventsResponse & other) const56449 bool ObserveEventsResponse::operator==(const ObserveEventsResponse& other) const {
56450   return unknown_fields_ == other.unknown_fields_
56451    && events_ == other.events_;
56452 }
56453 
ParseFromArray(const void * raw,size_t size)56454 bool ObserveEventsResponse::ParseFromArray(const void* raw, size_t size) {
56455   unknown_fields_.clear();
56456   bool packed_error = false;
56457 
56458   ::protozero::ProtoDecoder dec(raw, size);
56459   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
56460     if (field.id() < _has_field_.size()) {
56461       _has_field_.set(field.id());
56462     }
56463     switch (field.id()) {
56464       case 1 /* events */:
56465         (*events_).ParseFromArray(field.data(), field.size());
56466         break;
56467       default:
56468         field.SerializeAndAppendTo(&unknown_fields_);
56469         break;
56470     }
56471   }
56472   return !packed_error && !dec.bytes_left();
56473 }
56474 
SerializeAsString() const56475 std::string ObserveEventsResponse::SerializeAsString() const {
56476   ::protozero::HeapBuffered<::protozero::Message> msg;
56477   Serialize(msg.get());
56478   return msg.SerializeAsString();
56479 }
56480 
SerializeAsArray() const56481 std::vector<uint8_t> ObserveEventsResponse::SerializeAsArray() const {
56482   ::protozero::HeapBuffered<::protozero::Message> msg;
56483   Serialize(msg.get());
56484   return msg.SerializeAsArray();
56485 }
56486 
Serialize(::protozero::Message * msg) const56487 void ObserveEventsResponse::Serialize(::protozero::Message* msg) const {
56488   // Field 1: events
56489   if (_has_field_[1]) {
56490     (*events_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
56491   }
56492 
56493   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
56494 }
56495 
56496 
56497 ObserveEventsRequest::ObserveEventsRequest() = default;
56498 ObserveEventsRequest::~ObserveEventsRequest() = default;
56499 ObserveEventsRequest::ObserveEventsRequest(const ObserveEventsRequest&) = default;
56500 ObserveEventsRequest& ObserveEventsRequest::operator=(const ObserveEventsRequest&) = default;
56501 ObserveEventsRequest::ObserveEventsRequest(ObserveEventsRequest&&) noexcept = default;
56502 ObserveEventsRequest& ObserveEventsRequest::operator=(ObserveEventsRequest&&) = default;
56503 
operator ==(const ObserveEventsRequest & other) const56504 bool ObserveEventsRequest::operator==(const ObserveEventsRequest& other) const {
56505   return unknown_fields_ == other.unknown_fields_
56506    && events_to_observe_ == other.events_to_observe_;
56507 }
56508 
ParseFromArray(const void * raw,size_t size)56509 bool ObserveEventsRequest::ParseFromArray(const void* raw, size_t size) {
56510   events_to_observe_.clear();
56511   unknown_fields_.clear();
56512   bool packed_error = false;
56513 
56514   ::protozero::ProtoDecoder dec(raw, size);
56515   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
56516     if (field.id() < _has_field_.size()) {
56517       _has_field_.set(field.id());
56518     }
56519     switch (field.id()) {
56520       case 1 /* events_to_observe */:
56521         events_to_observe_.emplace_back();
56522         field.get(&events_to_observe_.back());
56523         break;
56524       default:
56525         field.SerializeAndAppendTo(&unknown_fields_);
56526         break;
56527     }
56528   }
56529   return !packed_error && !dec.bytes_left();
56530 }
56531 
SerializeAsString() const56532 std::string ObserveEventsRequest::SerializeAsString() const {
56533   ::protozero::HeapBuffered<::protozero::Message> msg;
56534   Serialize(msg.get());
56535   return msg.SerializeAsString();
56536 }
56537 
SerializeAsArray() const56538 std::vector<uint8_t> ObserveEventsRequest::SerializeAsArray() const {
56539   ::protozero::HeapBuffered<::protozero::Message> msg;
56540   Serialize(msg.get());
56541   return msg.SerializeAsArray();
56542 }
56543 
Serialize(::protozero::Message * msg) const56544 void ObserveEventsRequest::Serialize(::protozero::Message* msg) const {
56545   // Field 1: events_to_observe
56546   for (auto& it : events_to_observe_) {
56547     msg->AppendVarInt(1, it);
56548   }
56549 
56550   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
56551 }
56552 
56553 
56554 GetTraceStatsResponse::GetTraceStatsResponse() = default;
56555 GetTraceStatsResponse::~GetTraceStatsResponse() = default;
56556 GetTraceStatsResponse::GetTraceStatsResponse(const GetTraceStatsResponse&) = default;
56557 GetTraceStatsResponse& GetTraceStatsResponse::operator=(const GetTraceStatsResponse&) = default;
56558 GetTraceStatsResponse::GetTraceStatsResponse(GetTraceStatsResponse&&) noexcept = default;
56559 GetTraceStatsResponse& GetTraceStatsResponse::operator=(GetTraceStatsResponse&&) = default;
56560 
operator ==(const GetTraceStatsResponse & other) const56561 bool GetTraceStatsResponse::operator==(const GetTraceStatsResponse& other) const {
56562   return unknown_fields_ == other.unknown_fields_
56563    && trace_stats_ == other.trace_stats_;
56564 }
56565 
ParseFromArray(const void * raw,size_t size)56566 bool GetTraceStatsResponse::ParseFromArray(const void* raw, size_t size) {
56567   unknown_fields_.clear();
56568   bool packed_error = false;
56569 
56570   ::protozero::ProtoDecoder dec(raw, size);
56571   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
56572     if (field.id() < _has_field_.size()) {
56573       _has_field_.set(field.id());
56574     }
56575     switch (field.id()) {
56576       case 1 /* trace_stats */:
56577         (*trace_stats_).ParseFromArray(field.data(), field.size());
56578         break;
56579       default:
56580         field.SerializeAndAppendTo(&unknown_fields_);
56581         break;
56582     }
56583   }
56584   return !packed_error && !dec.bytes_left();
56585 }
56586 
SerializeAsString() const56587 std::string GetTraceStatsResponse::SerializeAsString() const {
56588   ::protozero::HeapBuffered<::protozero::Message> msg;
56589   Serialize(msg.get());
56590   return msg.SerializeAsString();
56591 }
56592 
SerializeAsArray() const56593 std::vector<uint8_t> GetTraceStatsResponse::SerializeAsArray() const {
56594   ::protozero::HeapBuffered<::protozero::Message> msg;
56595   Serialize(msg.get());
56596   return msg.SerializeAsArray();
56597 }
56598 
Serialize(::protozero::Message * msg) const56599 void GetTraceStatsResponse::Serialize(::protozero::Message* msg) const {
56600   // Field 1: trace_stats
56601   if (_has_field_[1]) {
56602     (*trace_stats_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
56603   }
56604 
56605   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
56606 }
56607 
56608 
56609 GetTraceStatsRequest::GetTraceStatsRequest() = default;
56610 GetTraceStatsRequest::~GetTraceStatsRequest() = default;
56611 GetTraceStatsRequest::GetTraceStatsRequest(const GetTraceStatsRequest&) = default;
56612 GetTraceStatsRequest& GetTraceStatsRequest::operator=(const GetTraceStatsRequest&) = default;
56613 GetTraceStatsRequest::GetTraceStatsRequest(GetTraceStatsRequest&&) noexcept = default;
56614 GetTraceStatsRequest& GetTraceStatsRequest::operator=(GetTraceStatsRequest&&) = default;
56615 
operator ==(const GetTraceStatsRequest & other) const56616 bool GetTraceStatsRequest::operator==(const GetTraceStatsRequest& other) const {
56617   return unknown_fields_ == other.unknown_fields_;
56618 }
56619 
ParseFromArray(const void * raw,size_t size)56620 bool GetTraceStatsRequest::ParseFromArray(const void* raw, size_t size) {
56621   unknown_fields_.clear();
56622   bool packed_error = false;
56623 
56624   ::protozero::ProtoDecoder dec(raw, size);
56625   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
56626     if (field.id() < _has_field_.size()) {
56627       _has_field_.set(field.id());
56628     }
56629     switch (field.id()) {
56630       default:
56631         field.SerializeAndAppendTo(&unknown_fields_);
56632         break;
56633     }
56634   }
56635   return !packed_error && !dec.bytes_left();
56636 }
56637 
SerializeAsString() const56638 std::string GetTraceStatsRequest::SerializeAsString() const {
56639   ::protozero::HeapBuffered<::protozero::Message> msg;
56640   Serialize(msg.get());
56641   return msg.SerializeAsString();
56642 }
56643 
SerializeAsArray() const56644 std::vector<uint8_t> GetTraceStatsRequest::SerializeAsArray() const {
56645   ::protozero::HeapBuffered<::protozero::Message> msg;
56646   Serialize(msg.get());
56647   return msg.SerializeAsArray();
56648 }
56649 
Serialize(::protozero::Message * msg) const56650 void GetTraceStatsRequest::Serialize(::protozero::Message* msg) const {
56651   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
56652 }
56653 
56654 
56655 AttachResponse::AttachResponse() = default;
56656 AttachResponse::~AttachResponse() = default;
56657 AttachResponse::AttachResponse(const AttachResponse&) = default;
56658 AttachResponse& AttachResponse::operator=(const AttachResponse&) = default;
56659 AttachResponse::AttachResponse(AttachResponse&&) noexcept = default;
56660 AttachResponse& AttachResponse::operator=(AttachResponse&&) = default;
56661 
operator ==(const AttachResponse & other) const56662 bool AttachResponse::operator==(const AttachResponse& other) const {
56663   return unknown_fields_ == other.unknown_fields_
56664    && trace_config_ == other.trace_config_;
56665 }
56666 
ParseFromArray(const void * raw,size_t size)56667 bool AttachResponse::ParseFromArray(const void* raw, size_t size) {
56668   unknown_fields_.clear();
56669   bool packed_error = false;
56670 
56671   ::protozero::ProtoDecoder dec(raw, size);
56672   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
56673     if (field.id() < _has_field_.size()) {
56674       _has_field_.set(field.id());
56675     }
56676     switch (field.id()) {
56677       case 1 /* trace_config */:
56678         (*trace_config_).ParseFromArray(field.data(), field.size());
56679         break;
56680       default:
56681         field.SerializeAndAppendTo(&unknown_fields_);
56682         break;
56683     }
56684   }
56685   return !packed_error && !dec.bytes_left();
56686 }
56687 
SerializeAsString() const56688 std::string AttachResponse::SerializeAsString() const {
56689   ::protozero::HeapBuffered<::protozero::Message> msg;
56690   Serialize(msg.get());
56691   return msg.SerializeAsString();
56692 }
56693 
SerializeAsArray() const56694 std::vector<uint8_t> AttachResponse::SerializeAsArray() const {
56695   ::protozero::HeapBuffered<::protozero::Message> msg;
56696   Serialize(msg.get());
56697   return msg.SerializeAsArray();
56698 }
56699 
Serialize(::protozero::Message * msg) const56700 void AttachResponse::Serialize(::protozero::Message* msg) const {
56701   // Field 1: trace_config
56702   if (_has_field_[1]) {
56703     (*trace_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
56704   }
56705 
56706   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
56707 }
56708 
56709 
56710 AttachRequest::AttachRequest() = default;
56711 AttachRequest::~AttachRequest() = default;
56712 AttachRequest::AttachRequest(const AttachRequest&) = default;
56713 AttachRequest& AttachRequest::operator=(const AttachRequest&) = default;
56714 AttachRequest::AttachRequest(AttachRequest&&) noexcept = default;
56715 AttachRequest& AttachRequest::operator=(AttachRequest&&) = default;
56716 
operator ==(const AttachRequest & other) const56717 bool AttachRequest::operator==(const AttachRequest& other) const {
56718   return unknown_fields_ == other.unknown_fields_
56719    && key_ == other.key_;
56720 }
56721 
ParseFromArray(const void * raw,size_t size)56722 bool AttachRequest::ParseFromArray(const void* raw, size_t size) {
56723   unknown_fields_.clear();
56724   bool packed_error = false;
56725 
56726   ::protozero::ProtoDecoder dec(raw, size);
56727   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
56728     if (field.id() < _has_field_.size()) {
56729       _has_field_.set(field.id());
56730     }
56731     switch (field.id()) {
56732       case 1 /* key */:
56733         field.get(&key_);
56734         break;
56735       default:
56736         field.SerializeAndAppendTo(&unknown_fields_);
56737         break;
56738     }
56739   }
56740   return !packed_error && !dec.bytes_left();
56741 }
56742 
SerializeAsString() const56743 std::string AttachRequest::SerializeAsString() const {
56744   ::protozero::HeapBuffered<::protozero::Message> msg;
56745   Serialize(msg.get());
56746   return msg.SerializeAsString();
56747 }
56748 
SerializeAsArray() const56749 std::vector<uint8_t> AttachRequest::SerializeAsArray() const {
56750   ::protozero::HeapBuffered<::protozero::Message> msg;
56751   Serialize(msg.get());
56752   return msg.SerializeAsArray();
56753 }
56754 
Serialize(::protozero::Message * msg) const56755 void AttachRequest::Serialize(::protozero::Message* msg) const {
56756   // Field 1: key
56757   if (_has_field_[1]) {
56758     msg->AppendString(1, key_);
56759   }
56760 
56761   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
56762 }
56763 
56764 
56765 DetachResponse::DetachResponse() = default;
56766 DetachResponse::~DetachResponse() = default;
56767 DetachResponse::DetachResponse(const DetachResponse&) = default;
56768 DetachResponse& DetachResponse::operator=(const DetachResponse&) = default;
56769 DetachResponse::DetachResponse(DetachResponse&&) noexcept = default;
56770 DetachResponse& DetachResponse::operator=(DetachResponse&&) = default;
56771 
operator ==(const DetachResponse & other) const56772 bool DetachResponse::operator==(const DetachResponse& other) const {
56773   return unknown_fields_ == other.unknown_fields_;
56774 }
56775 
ParseFromArray(const void * raw,size_t size)56776 bool DetachResponse::ParseFromArray(const void* raw, size_t size) {
56777   unknown_fields_.clear();
56778   bool packed_error = false;
56779 
56780   ::protozero::ProtoDecoder dec(raw, size);
56781   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
56782     if (field.id() < _has_field_.size()) {
56783       _has_field_.set(field.id());
56784     }
56785     switch (field.id()) {
56786       default:
56787         field.SerializeAndAppendTo(&unknown_fields_);
56788         break;
56789     }
56790   }
56791   return !packed_error && !dec.bytes_left();
56792 }
56793 
SerializeAsString() const56794 std::string DetachResponse::SerializeAsString() const {
56795   ::protozero::HeapBuffered<::protozero::Message> msg;
56796   Serialize(msg.get());
56797   return msg.SerializeAsString();
56798 }
56799 
SerializeAsArray() const56800 std::vector<uint8_t> DetachResponse::SerializeAsArray() const {
56801   ::protozero::HeapBuffered<::protozero::Message> msg;
56802   Serialize(msg.get());
56803   return msg.SerializeAsArray();
56804 }
56805 
Serialize(::protozero::Message * msg) const56806 void DetachResponse::Serialize(::protozero::Message* msg) const {
56807   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
56808 }
56809 
56810 
56811 DetachRequest::DetachRequest() = default;
56812 DetachRequest::~DetachRequest() = default;
56813 DetachRequest::DetachRequest(const DetachRequest&) = default;
56814 DetachRequest& DetachRequest::operator=(const DetachRequest&) = default;
56815 DetachRequest::DetachRequest(DetachRequest&&) noexcept = default;
56816 DetachRequest& DetachRequest::operator=(DetachRequest&&) = default;
56817 
operator ==(const DetachRequest & other) const56818 bool DetachRequest::operator==(const DetachRequest& other) const {
56819   return unknown_fields_ == other.unknown_fields_
56820    && key_ == other.key_;
56821 }
56822 
ParseFromArray(const void * raw,size_t size)56823 bool DetachRequest::ParseFromArray(const void* raw, size_t size) {
56824   unknown_fields_.clear();
56825   bool packed_error = false;
56826 
56827   ::protozero::ProtoDecoder dec(raw, size);
56828   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
56829     if (field.id() < _has_field_.size()) {
56830       _has_field_.set(field.id());
56831     }
56832     switch (field.id()) {
56833       case 1 /* key */:
56834         field.get(&key_);
56835         break;
56836       default:
56837         field.SerializeAndAppendTo(&unknown_fields_);
56838         break;
56839     }
56840   }
56841   return !packed_error && !dec.bytes_left();
56842 }
56843 
SerializeAsString() const56844 std::string DetachRequest::SerializeAsString() const {
56845   ::protozero::HeapBuffered<::protozero::Message> msg;
56846   Serialize(msg.get());
56847   return msg.SerializeAsString();
56848 }
56849 
SerializeAsArray() const56850 std::vector<uint8_t> DetachRequest::SerializeAsArray() const {
56851   ::protozero::HeapBuffered<::protozero::Message> msg;
56852   Serialize(msg.get());
56853   return msg.SerializeAsArray();
56854 }
56855 
Serialize(::protozero::Message * msg) const56856 void DetachRequest::Serialize(::protozero::Message* msg) const {
56857   // Field 1: key
56858   if (_has_field_[1]) {
56859     msg->AppendString(1, key_);
56860   }
56861 
56862   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
56863 }
56864 
56865 
56866 FlushResponse::FlushResponse() = default;
56867 FlushResponse::~FlushResponse() = default;
56868 FlushResponse::FlushResponse(const FlushResponse&) = default;
56869 FlushResponse& FlushResponse::operator=(const FlushResponse&) = default;
56870 FlushResponse::FlushResponse(FlushResponse&&) noexcept = default;
56871 FlushResponse& FlushResponse::operator=(FlushResponse&&) = default;
56872 
operator ==(const FlushResponse & other) const56873 bool FlushResponse::operator==(const FlushResponse& other) const {
56874   return unknown_fields_ == other.unknown_fields_;
56875 }
56876 
ParseFromArray(const void * raw,size_t size)56877 bool FlushResponse::ParseFromArray(const void* raw, size_t size) {
56878   unknown_fields_.clear();
56879   bool packed_error = false;
56880 
56881   ::protozero::ProtoDecoder dec(raw, size);
56882   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
56883     if (field.id() < _has_field_.size()) {
56884       _has_field_.set(field.id());
56885     }
56886     switch (field.id()) {
56887       default:
56888         field.SerializeAndAppendTo(&unknown_fields_);
56889         break;
56890     }
56891   }
56892   return !packed_error && !dec.bytes_left();
56893 }
56894 
SerializeAsString() const56895 std::string FlushResponse::SerializeAsString() const {
56896   ::protozero::HeapBuffered<::protozero::Message> msg;
56897   Serialize(msg.get());
56898   return msg.SerializeAsString();
56899 }
56900 
SerializeAsArray() const56901 std::vector<uint8_t> FlushResponse::SerializeAsArray() const {
56902   ::protozero::HeapBuffered<::protozero::Message> msg;
56903   Serialize(msg.get());
56904   return msg.SerializeAsArray();
56905 }
56906 
Serialize(::protozero::Message * msg) const56907 void FlushResponse::Serialize(::protozero::Message* msg) const {
56908   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
56909 }
56910 
56911 
56912 FlushRequest::FlushRequest() = default;
56913 FlushRequest::~FlushRequest() = default;
56914 FlushRequest::FlushRequest(const FlushRequest&) = default;
56915 FlushRequest& FlushRequest::operator=(const FlushRequest&) = default;
56916 FlushRequest::FlushRequest(FlushRequest&&) noexcept = default;
56917 FlushRequest& FlushRequest::operator=(FlushRequest&&) = default;
56918 
operator ==(const FlushRequest & other) const56919 bool FlushRequest::operator==(const FlushRequest& other) const {
56920   return unknown_fields_ == other.unknown_fields_
56921    && timeout_ms_ == other.timeout_ms_;
56922 }
56923 
ParseFromArray(const void * raw,size_t size)56924 bool FlushRequest::ParseFromArray(const void* raw, size_t size) {
56925   unknown_fields_.clear();
56926   bool packed_error = false;
56927 
56928   ::protozero::ProtoDecoder dec(raw, size);
56929   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
56930     if (field.id() < _has_field_.size()) {
56931       _has_field_.set(field.id());
56932     }
56933     switch (field.id()) {
56934       case 1 /* timeout_ms */:
56935         field.get(&timeout_ms_);
56936         break;
56937       default:
56938         field.SerializeAndAppendTo(&unknown_fields_);
56939         break;
56940     }
56941   }
56942   return !packed_error && !dec.bytes_left();
56943 }
56944 
SerializeAsString() const56945 std::string FlushRequest::SerializeAsString() const {
56946   ::protozero::HeapBuffered<::protozero::Message> msg;
56947   Serialize(msg.get());
56948   return msg.SerializeAsString();
56949 }
56950 
SerializeAsArray() const56951 std::vector<uint8_t> FlushRequest::SerializeAsArray() const {
56952   ::protozero::HeapBuffered<::protozero::Message> msg;
56953   Serialize(msg.get());
56954   return msg.SerializeAsArray();
56955 }
56956 
Serialize(::protozero::Message * msg) const56957 void FlushRequest::Serialize(::protozero::Message* msg) const {
56958   // Field 1: timeout_ms
56959   if (_has_field_[1]) {
56960     msg->AppendVarInt(1, timeout_ms_);
56961   }
56962 
56963   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
56964 }
56965 
56966 
56967 FreeBuffersResponse::FreeBuffersResponse() = default;
56968 FreeBuffersResponse::~FreeBuffersResponse() = default;
56969 FreeBuffersResponse::FreeBuffersResponse(const FreeBuffersResponse&) = default;
56970 FreeBuffersResponse& FreeBuffersResponse::operator=(const FreeBuffersResponse&) = default;
56971 FreeBuffersResponse::FreeBuffersResponse(FreeBuffersResponse&&) noexcept = default;
56972 FreeBuffersResponse& FreeBuffersResponse::operator=(FreeBuffersResponse&&) = default;
56973 
operator ==(const FreeBuffersResponse & other) const56974 bool FreeBuffersResponse::operator==(const FreeBuffersResponse& other) const {
56975   return unknown_fields_ == other.unknown_fields_;
56976 }
56977 
ParseFromArray(const void * raw,size_t size)56978 bool FreeBuffersResponse::ParseFromArray(const void* raw, size_t size) {
56979   unknown_fields_.clear();
56980   bool packed_error = false;
56981 
56982   ::protozero::ProtoDecoder dec(raw, size);
56983   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
56984     if (field.id() < _has_field_.size()) {
56985       _has_field_.set(field.id());
56986     }
56987     switch (field.id()) {
56988       default:
56989         field.SerializeAndAppendTo(&unknown_fields_);
56990         break;
56991     }
56992   }
56993   return !packed_error && !dec.bytes_left();
56994 }
56995 
SerializeAsString() const56996 std::string FreeBuffersResponse::SerializeAsString() const {
56997   ::protozero::HeapBuffered<::protozero::Message> msg;
56998   Serialize(msg.get());
56999   return msg.SerializeAsString();
57000 }
57001 
SerializeAsArray() const57002 std::vector<uint8_t> FreeBuffersResponse::SerializeAsArray() const {
57003   ::protozero::HeapBuffered<::protozero::Message> msg;
57004   Serialize(msg.get());
57005   return msg.SerializeAsArray();
57006 }
57007 
Serialize(::protozero::Message * msg) const57008 void FreeBuffersResponse::Serialize(::protozero::Message* msg) const {
57009   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
57010 }
57011 
57012 
57013 FreeBuffersRequest::FreeBuffersRequest() = default;
57014 FreeBuffersRequest::~FreeBuffersRequest() = default;
57015 FreeBuffersRequest::FreeBuffersRequest(const FreeBuffersRequest&) = default;
57016 FreeBuffersRequest& FreeBuffersRequest::operator=(const FreeBuffersRequest&) = default;
57017 FreeBuffersRequest::FreeBuffersRequest(FreeBuffersRequest&&) noexcept = default;
57018 FreeBuffersRequest& FreeBuffersRequest::operator=(FreeBuffersRequest&&) = default;
57019 
operator ==(const FreeBuffersRequest & other) const57020 bool FreeBuffersRequest::operator==(const FreeBuffersRequest& other) const {
57021   return unknown_fields_ == other.unknown_fields_
57022    && buffer_ids_ == other.buffer_ids_;
57023 }
57024 
ParseFromArray(const void * raw,size_t size)57025 bool FreeBuffersRequest::ParseFromArray(const void* raw, size_t size) {
57026   buffer_ids_.clear();
57027   unknown_fields_.clear();
57028   bool packed_error = false;
57029 
57030   ::protozero::ProtoDecoder dec(raw, size);
57031   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
57032     if (field.id() < _has_field_.size()) {
57033       _has_field_.set(field.id());
57034     }
57035     switch (field.id()) {
57036       case 1 /* buffer_ids */:
57037         buffer_ids_.emplace_back();
57038         field.get(&buffer_ids_.back());
57039         break;
57040       default:
57041         field.SerializeAndAppendTo(&unknown_fields_);
57042         break;
57043     }
57044   }
57045   return !packed_error && !dec.bytes_left();
57046 }
57047 
SerializeAsString() const57048 std::string FreeBuffersRequest::SerializeAsString() const {
57049   ::protozero::HeapBuffered<::protozero::Message> msg;
57050   Serialize(msg.get());
57051   return msg.SerializeAsString();
57052 }
57053 
SerializeAsArray() const57054 std::vector<uint8_t> FreeBuffersRequest::SerializeAsArray() const {
57055   ::protozero::HeapBuffered<::protozero::Message> msg;
57056   Serialize(msg.get());
57057   return msg.SerializeAsArray();
57058 }
57059 
Serialize(::protozero::Message * msg) const57060 void FreeBuffersRequest::Serialize(::protozero::Message* msg) const {
57061   // Field 1: buffer_ids
57062   for (auto& it : buffer_ids_) {
57063     msg->AppendVarInt(1, it);
57064   }
57065 
57066   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
57067 }
57068 
57069 
57070 ReadBuffersResponse::ReadBuffersResponse() = default;
57071 ReadBuffersResponse::~ReadBuffersResponse() = default;
57072 ReadBuffersResponse::ReadBuffersResponse(const ReadBuffersResponse&) = default;
57073 ReadBuffersResponse& ReadBuffersResponse::operator=(const ReadBuffersResponse&) = default;
57074 ReadBuffersResponse::ReadBuffersResponse(ReadBuffersResponse&&) noexcept = default;
57075 ReadBuffersResponse& ReadBuffersResponse::operator=(ReadBuffersResponse&&) = default;
57076 
operator ==(const ReadBuffersResponse & other) const57077 bool ReadBuffersResponse::operator==(const ReadBuffersResponse& other) const {
57078   return unknown_fields_ == other.unknown_fields_
57079    && slices_ == other.slices_;
57080 }
57081 
slices_size() const57082 int ReadBuffersResponse::slices_size() const { return static_cast<int>(slices_.size()); }
clear_slices()57083 void ReadBuffersResponse::clear_slices() { slices_.clear(); }
add_slices()57084 ReadBuffersResponse_Slice* ReadBuffersResponse::add_slices() { slices_.emplace_back(); return &slices_.back(); }
ParseFromArray(const void * raw,size_t size)57085 bool ReadBuffersResponse::ParseFromArray(const void* raw, size_t size) {
57086   slices_.clear();
57087   unknown_fields_.clear();
57088   bool packed_error = false;
57089 
57090   ::protozero::ProtoDecoder dec(raw, size);
57091   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
57092     if (field.id() < _has_field_.size()) {
57093       _has_field_.set(field.id());
57094     }
57095     switch (field.id()) {
57096       case 2 /* slices */:
57097         slices_.emplace_back();
57098         slices_.back().ParseFromArray(field.data(), field.size());
57099         break;
57100       default:
57101         field.SerializeAndAppendTo(&unknown_fields_);
57102         break;
57103     }
57104   }
57105   return !packed_error && !dec.bytes_left();
57106 }
57107 
SerializeAsString() const57108 std::string ReadBuffersResponse::SerializeAsString() const {
57109   ::protozero::HeapBuffered<::protozero::Message> msg;
57110   Serialize(msg.get());
57111   return msg.SerializeAsString();
57112 }
57113 
SerializeAsArray() const57114 std::vector<uint8_t> ReadBuffersResponse::SerializeAsArray() const {
57115   ::protozero::HeapBuffered<::protozero::Message> msg;
57116   Serialize(msg.get());
57117   return msg.SerializeAsArray();
57118 }
57119 
Serialize(::protozero::Message * msg) const57120 void ReadBuffersResponse::Serialize(::protozero::Message* msg) const {
57121   // Field 2: slices
57122   for (auto& it : slices_) {
57123     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
57124   }
57125 
57126   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
57127 }
57128 
57129 
57130 ReadBuffersResponse_Slice::ReadBuffersResponse_Slice() = default;
57131 ReadBuffersResponse_Slice::~ReadBuffersResponse_Slice() = default;
57132 ReadBuffersResponse_Slice::ReadBuffersResponse_Slice(const ReadBuffersResponse_Slice&) = default;
57133 ReadBuffersResponse_Slice& ReadBuffersResponse_Slice::operator=(const ReadBuffersResponse_Slice&) = default;
57134 ReadBuffersResponse_Slice::ReadBuffersResponse_Slice(ReadBuffersResponse_Slice&&) noexcept = default;
57135 ReadBuffersResponse_Slice& ReadBuffersResponse_Slice::operator=(ReadBuffersResponse_Slice&&) = default;
57136 
operator ==(const ReadBuffersResponse_Slice & other) const57137 bool ReadBuffersResponse_Slice::operator==(const ReadBuffersResponse_Slice& other) const {
57138   return unknown_fields_ == other.unknown_fields_
57139    && data_ == other.data_
57140    && last_slice_for_packet_ == other.last_slice_for_packet_;
57141 }
57142 
ParseFromArray(const void * raw,size_t size)57143 bool ReadBuffersResponse_Slice::ParseFromArray(const void* raw, size_t size) {
57144   unknown_fields_.clear();
57145   bool packed_error = false;
57146 
57147   ::protozero::ProtoDecoder dec(raw, size);
57148   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
57149     if (field.id() < _has_field_.size()) {
57150       _has_field_.set(field.id());
57151     }
57152     switch (field.id()) {
57153       case 1 /* data */:
57154         field.get(&data_);
57155         break;
57156       case 2 /* last_slice_for_packet */:
57157         field.get(&last_slice_for_packet_);
57158         break;
57159       default:
57160         field.SerializeAndAppendTo(&unknown_fields_);
57161         break;
57162     }
57163   }
57164   return !packed_error && !dec.bytes_left();
57165 }
57166 
SerializeAsString() const57167 std::string ReadBuffersResponse_Slice::SerializeAsString() const {
57168   ::protozero::HeapBuffered<::protozero::Message> msg;
57169   Serialize(msg.get());
57170   return msg.SerializeAsString();
57171 }
57172 
SerializeAsArray() const57173 std::vector<uint8_t> ReadBuffersResponse_Slice::SerializeAsArray() const {
57174   ::protozero::HeapBuffered<::protozero::Message> msg;
57175   Serialize(msg.get());
57176   return msg.SerializeAsArray();
57177 }
57178 
Serialize(::protozero::Message * msg) const57179 void ReadBuffersResponse_Slice::Serialize(::protozero::Message* msg) const {
57180   // Field 1: data
57181   if (_has_field_[1]) {
57182     msg->AppendString(1, data_);
57183   }
57184 
57185   // Field 2: last_slice_for_packet
57186   if (_has_field_[2]) {
57187     msg->AppendTinyVarInt(2, last_slice_for_packet_);
57188   }
57189 
57190   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
57191 }
57192 
57193 
57194 ReadBuffersRequest::ReadBuffersRequest() = default;
57195 ReadBuffersRequest::~ReadBuffersRequest() = default;
57196 ReadBuffersRequest::ReadBuffersRequest(const ReadBuffersRequest&) = default;
57197 ReadBuffersRequest& ReadBuffersRequest::operator=(const ReadBuffersRequest&) = default;
57198 ReadBuffersRequest::ReadBuffersRequest(ReadBuffersRequest&&) noexcept = default;
57199 ReadBuffersRequest& ReadBuffersRequest::operator=(ReadBuffersRequest&&) = default;
57200 
operator ==(const ReadBuffersRequest & other) const57201 bool ReadBuffersRequest::operator==(const ReadBuffersRequest& other) const {
57202   return unknown_fields_ == other.unknown_fields_;
57203 }
57204 
ParseFromArray(const void * raw,size_t size)57205 bool ReadBuffersRequest::ParseFromArray(const void* raw, size_t size) {
57206   unknown_fields_.clear();
57207   bool packed_error = false;
57208 
57209   ::protozero::ProtoDecoder dec(raw, size);
57210   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
57211     if (field.id() < _has_field_.size()) {
57212       _has_field_.set(field.id());
57213     }
57214     switch (field.id()) {
57215       default:
57216         field.SerializeAndAppendTo(&unknown_fields_);
57217         break;
57218     }
57219   }
57220   return !packed_error && !dec.bytes_left();
57221 }
57222 
SerializeAsString() const57223 std::string ReadBuffersRequest::SerializeAsString() const {
57224   ::protozero::HeapBuffered<::protozero::Message> msg;
57225   Serialize(msg.get());
57226   return msg.SerializeAsString();
57227 }
57228 
SerializeAsArray() const57229 std::vector<uint8_t> ReadBuffersRequest::SerializeAsArray() const {
57230   ::protozero::HeapBuffered<::protozero::Message> msg;
57231   Serialize(msg.get());
57232   return msg.SerializeAsArray();
57233 }
57234 
Serialize(::protozero::Message * msg) const57235 void ReadBuffersRequest::Serialize(::protozero::Message* msg) const {
57236   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
57237 }
57238 
57239 
57240 DisableTracingResponse::DisableTracingResponse() = default;
57241 DisableTracingResponse::~DisableTracingResponse() = default;
57242 DisableTracingResponse::DisableTracingResponse(const DisableTracingResponse&) = default;
57243 DisableTracingResponse& DisableTracingResponse::operator=(const DisableTracingResponse&) = default;
57244 DisableTracingResponse::DisableTracingResponse(DisableTracingResponse&&) noexcept = default;
57245 DisableTracingResponse& DisableTracingResponse::operator=(DisableTracingResponse&&) = default;
57246 
operator ==(const DisableTracingResponse & other) const57247 bool DisableTracingResponse::operator==(const DisableTracingResponse& other) const {
57248   return unknown_fields_ == other.unknown_fields_;
57249 }
57250 
ParseFromArray(const void * raw,size_t size)57251 bool DisableTracingResponse::ParseFromArray(const void* raw, size_t size) {
57252   unknown_fields_.clear();
57253   bool packed_error = false;
57254 
57255   ::protozero::ProtoDecoder dec(raw, size);
57256   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
57257     if (field.id() < _has_field_.size()) {
57258       _has_field_.set(field.id());
57259     }
57260     switch (field.id()) {
57261       default:
57262         field.SerializeAndAppendTo(&unknown_fields_);
57263         break;
57264     }
57265   }
57266   return !packed_error && !dec.bytes_left();
57267 }
57268 
SerializeAsString() const57269 std::string DisableTracingResponse::SerializeAsString() const {
57270   ::protozero::HeapBuffered<::protozero::Message> msg;
57271   Serialize(msg.get());
57272   return msg.SerializeAsString();
57273 }
57274 
SerializeAsArray() const57275 std::vector<uint8_t> DisableTracingResponse::SerializeAsArray() const {
57276   ::protozero::HeapBuffered<::protozero::Message> msg;
57277   Serialize(msg.get());
57278   return msg.SerializeAsArray();
57279 }
57280 
Serialize(::protozero::Message * msg) const57281 void DisableTracingResponse::Serialize(::protozero::Message* msg) const {
57282   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
57283 }
57284 
57285 
57286 DisableTracingRequest::DisableTracingRequest() = default;
57287 DisableTracingRequest::~DisableTracingRequest() = default;
57288 DisableTracingRequest::DisableTracingRequest(const DisableTracingRequest&) = default;
57289 DisableTracingRequest& DisableTracingRequest::operator=(const DisableTracingRequest&) = default;
57290 DisableTracingRequest::DisableTracingRequest(DisableTracingRequest&&) noexcept = default;
57291 DisableTracingRequest& DisableTracingRequest::operator=(DisableTracingRequest&&) = default;
57292 
operator ==(const DisableTracingRequest & other) const57293 bool DisableTracingRequest::operator==(const DisableTracingRequest& other) const {
57294   return unknown_fields_ == other.unknown_fields_;
57295 }
57296 
ParseFromArray(const void * raw,size_t size)57297 bool DisableTracingRequest::ParseFromArray(const void* raw, size_t size) {
57298   unknown_fields_.clear();
57299   bool packed_error = false;
57300 
57301   ::protozero::ProtoDecoder dec(raw, size);
57302   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
57303     if (field.id() < _has_field_.size()) {
57304       _has_field_.set(field.id());
57305     }
57306     switch (field.id()) {
57307       default:
57308         field.SerializeAndAppendTo(&unknown_fields_);
57309         break;
57310     }
57311   }
57312   return !packed_error && !dec.bytes_left();
57313 }
57314 
SerializeAsString() const57315 std::string DisableTracingRequest::SerializeAsString() const {
57316   ::protozero::HeapBuffered<::protozero::Message> msg;
57317   Serialize(msg.get());
57318   return msg.SerializeAsString();
57319 }
57320 
SerializeAsArray() const57321 std::vector<uint8_t> DisableTracingRequest::SerializeAsArray() const {
57322   ::protozero::HeapBuffered<::protozero::Message> msg;
57323   Serialize(msg.get());
57324   return msg.SerializeAsArray();
57325 }
57326 
Serialize(::protozero::Message * msg) const57327 void DisableTracingRequest::Serialize(::protozero::Message* msg) const {
57328   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
57329 }
57330 
57331 
57332 ChangeTraceConfigResponse::ChangeTraceConfigResponse() = default;
57333 ChangeTraceConfigResponse::~ChangeTraceConfigResponse() = default;
57334 ChangeTraceConfigResponse::ChangeTraceConfigResponse(const ChangeTraceConfigResponse&) = default;
57335 ChangeTraceConfigResponse& ChangeTraceConfigResponse::operator=(const ChangeTraceConfigResponse&) = default;
57336 ChangeTraceConfigResponse::ChangeTraceConfigResponse(ChangeTraceConfigResponse&&) noexcept = default;
57337 ChangeTraceConfigResponse& ChangeTraceConfigResponse::operator=(ChangeTraceConfigResponse&&) = default;
57338 
operator ==(const ChangeTraceConfigResponse & other) const57339 bool ChangeTraceConfigResponse::operator==(const ChangeTraceConfigResponse& other) const {
57340   return unknown_fields_ == other.unknown_fields_;
57341 }
57342 
ParseFromArray(const void * raw,size_t size)57343 bool ChangeTraceConfigResponse::ParseFromArray(const void* raw, size_t size) {
57344   unknown_fields_.clear();
57345   bool packed_error = false;
57346 
57347   ::protozero::ProtoDecoder dec(raw, size);
57348   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
57349     if (field.id() < _has_field_.size()) {
57350       _has_field_.set(field.id());
57351     }
57352     switch (field.id()) {
57353       default:
57354         field.SerializeAndAppendTo(&unknown_fields_);
57355         break;
57356     }
57357   }
57358   return !packed_error && !dec.bytes_left();
57359 }
57360 
SerializeAsString() const57361 std::string ChangeTraceConfigResponse::SerializeAsString() const {
57362   ::protozero::HeapBuffered<::protozero::Message> msg;
57363   Serialize(msg.get());
57364   return msg.SerializeAsString();
57365 }
57366 
SerializeAsArray() const57367 std::vector<uint8_t> ChangeTraceConfigResponse::SerializeAsArray() const {
57368   ::protozero::HeapBuffered<::protozero::Message> msg;
57369   Serialize(msg.get());
57370   return msg.SerializeAsArray();
57371 }
57372 
Serialize(::protozero::Message * msg) const57373 void ChangeTraceConfigResponse::Serialize(::protozero::Message* msg) const {
57374   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
57375 }
57376 
57377 
57378 ChangeTraceConfigRequest::ChangeTraceConfigRequest() = default;
57379 ChangeTraceConfigRequest::~ChangeTraceConfigRequest() = default;
57380 ChangeTraceConfigRequest::ChangeTraceConfigRequest(const ChangeTraceConfigRequest&) = default;
57381 ChangeTraceConfigRequest& ChangeTraceConfigRequest::operator=(const ChangeTraceConfigRequest&) = default;
57382 ChangeTraceConfigRequest::ChangeTraceConfigRequest(ChangeTraceConfigRequest&&) noexcept = default;
57383 ChangeTraceConfigRequest& ChangeTraceConfigRequest::operator=(ChangeTraceConfigRequest&&) = default;
57384 
operator ==(const ChangeTraceConfigRequest & other) const57385 bool ChangeTraceConfigRequest::operator==(const ChangeTraceConfigRequest& other) const {
57386   return unknown_fields_ == other.unknown_fields_
57387    && trace_config_ == other.trace_config_;
57388 }
57389 
ParseFromArray(const void * raw,size_t size)57390 bool ChangeTraceConfigRequest::ParseFromArray(const void* raw, size_t size) {
57391   unknown_fields_.clear();
57392   bool packed_error = false;
57393 
57394   ::protozero::ProtoDecoder dec(raw, size);
57395   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
57396     if (field.id() < _has_field_.size()) {
57397       _has_field_.set(field.id());
57398     }
57399     switch (field.id()) {
57400       case 1 /* trace_config */:
57401         (*trace_config_).ParseFromArray(field.data(), field.size());
57402         break;
57403       default:
57404         field.SerializeAndAppendTo(&unknown_fields_);
57405         break;
57406     }
57407   }
57408   return !packed_error && !dec.bytes_left();
57409 }
57410 
SerializeAsString() const57411 std::string ChangeTraceConfigRequest::SerializeAsString() const {
57412   ::protozero::HeapBuffered<::protozero::Message> msg;
57413   Serialize(msg.get());
57414   return msg.SerializeAsString();
57415 }
57416 
SerializeAsArray() const57417 std::vector<uint8_t> ChangeTraceConfigRequest::SerializeAsArray() const {
57418   ::protozero::HeapBuffered<::protozero::Message> msg;
57419   Serialize(msg.get());
57420   return msg.SerializeAsArray();
57421 }
57422 
Serialize(::protozero::Message * msg) const57423 void ChangeTraceConfigRequest::Serialize(::protozero::Message* msg) const {
57424   // Field 1: trace_config
57425   if (_has_field_[1]) {
57426     (*trace_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
57427   }
57428 
57429   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
57430 }
57431 
57432 
57433 StartTracingResponse::StartTracingResponse() = default;
57434 StartTracingResponse::~StartTracingResponse() = default;
57435 StartTracingResponse::StartTracingResponse(const StartTracingResponse&) = default;
57436 StartTracingResponse& StartTracingResponse::operator=(const StartTracingResponse&) = default;
57437 StartTracingResponse::StartTracingResponse(StartTracingResponse&&) noexcept = default;
57438 StartTracingResponse& StartTracingResponse::operator=(StartTracingResponse&&) = default;
57439 
operator ==(const StartTracingResponse & other) const57440 bool StartTracingResponse::operator==(const StartTracingResponse& other) const {
57441   return unknown_fields_ == other.unknown_fields_;
57442 }
57443 
ParseFromArray(const void * raw,size_t size)57444 bool StartTracingResponse::ParseFromArray(const void* raw, size_t size) {
57445   unknown_fields_.clear();
57446   bool packed_error = false;
57447 
57448   ::protozero::ProtoDecoder dec(raw, size);
57449   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
57450     if (field.id() < _has_field_.size()) {
57451       _has_field_.set(field.id());
57452     }
57453     switch (field.id()) {
57454       default:
57455         field.SerializeAndAppendTo(&unknown_fields_);
57456         break;
57457     }
57458   }
57459   return !packed_error && !dec.bytes_left();
57460 }
57461 
SerializeAsString() const57462 std::string StartTracingResponse::SerializeAsString() const {
57463   ::protozero::HeapBuffered<::protozero::Message> msg;
57464   Serialize(msg.get());
57465   return msg.SerializeAsString();
57466 }
57467 
SerializeAsArray() const57468 std::vector<uint8_t> StartTracingResponse::SerializeAsArray() const {
57469   ::protozero::HeapBuffered<::protozero::Message> msg;
57470   Serialize(msg.get());
57471   return msg.SerializeAsArray();
57472 }
57473 
Serialize(::protozero::Message * msg) const57474 void StartTracingResponse::Serialize(::protozero::Message* msg) const {
57475   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
57476 }
57477 
57478 
57479 StartTracingRequest::StartTracingRequest() = default;
57480 StartTracingRequest::~StartTracingRequest() = default;
57481 StartTracingRequest::StartTracingRequest(const StartTracingRequest&) = default;
57482 StartTracingRequest& StartTracingRequest::operator=(const StartTracingRequest&) = default;
57483 StartTracingRequest::StartTracingRequest(StartTracingRequest&&) noexcept = default;
57484 StartTracingRequest& StartTracingRequest::operator=(StartTracingRequest&&) = default;
57485 
operator ==(const StartTracingRequest & other) const57486 bool StartTracingRequest::operator==(const StartTracingRequest& other) const {
57487   return unknown_fields_ == other.unknown_fields_;
57488 }
57489 
ParseFromArray(const void * raw,size_t size)57490 bool StartTracingRequest::ParseFromArray(const void* raw, size_t size) {
57491   unknown_fields_.clear();
57492   bool packed_error = false;
57493 
57494   ::protozero::ProtoDecoder dec(raw, size);
57495   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
57496     if (field.id() < _has_field_.size()) {
57497       _has_field_.set(field.id());
57498     }
57499     switch (field.id()) {
57500       default:
57501         field.SerializeAndAppendTo(&unknown_fields_);
57502         break;
57503     }
57504   }
57505   return !packed_error && !dec.bytes_left();
57506 }
57507 
SerializeAsString() const57508 std::string StartTracingRequest::SerializeAsString() const {
57509   ::protozero::HeapBuffered<::protozero::Message> msg;
57510   Serialize(msg.get());
57511   return msg.SerializeAsString();
57512 }
57513 
SerializeAsArray() const57514 std::vector<uint8_t> StartTracingRequest::SerializeAsArray() const {
57515   ::protozero::HeapBuffered<::protozero::Message> msg;
57516   Serialize(msg.get());
57517   return msg.SerializeAsArray();
57518 }
57519 
Serialize(::protozero::Message * msg) const57520 void StartTracingRequest::Serialize(::protozero::Message* msg) const {
57521   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
57522 }
57523 
57524 
57525 EnableTracingResponse::EnableTracingResponse() = default;
57526 EnableTracingResponse::~EnableTracingResponse() = default;
57527 EnableTracingResponse::EnableTracingResponse(const EnableTracingResponse&) = default;
57528 EnableTracingResponse& EnableTracingResponse::operator=(const EnableTracingResponse&) = default;
57529 EnableTracingResponse::EnableTracingResponse(EnableTracingResponse&&) noexcept = default;
57530 EnableTracingResponse& EnableTracingResponse::operator=(EnableTracingResponse&&) = default;
57531 
operator ==(const EnableTracingResponse & other) const57532 bool EnableTracingResponse::operator==(const EnableTracingResponse& other) const {
57533   return unknown_fields_ == other.unknown_fields_
57534    && disabled_ == other.disabled_
57535    && error_ == other.error_;
57536 }
57537 
ParseFromArray(const void * raw,size_t size)57538 bool EnableTracingResponse::ParseFromArray(const void* raw, size_t size) {
57539   unknown_fields_.clear();
57540   bool packed_error = false;
57541 
57542   ::protozero::ProtoDecoder dec(raw, size);
57543   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
57544     if (field.id() < _has_field_.size()) {
57545       _has_field_.set(field.id());
57546     }
57547     switch (field.id()) {
57548       case 1 /* disabled */:
57549         field.get(&disabled_);
57550         break;
57551       case 3 /* error */:
57552         field.get(&error_);
57553         break;
57554       default:
57555         field.SerializeAndAppendTo(&unknown_fields_);
57556         break;
57557     }
57558   }
57559   return !packed_error && !dec.bytes_left();
57560 }
57561 
SerializeAsString() const57562 std::string EnableTracingResponse::SerializeAsString() const {
57563   ::protozero::HeapBuffered<::protozero::Message> msg;
57564   Serialize(msg.get());
57565   return msg.SerializeAsString();
57566 }
57567 
SerializeAsArray() const57568 std::vector<uint8_t> EnableTracingResponse::SerializeAsArray() const {
57569   ::protozero::HeapBuffered<::protozero::Message> msg;
57570   Serialize(msg.get());
57571   return msg.SerializeAsArray();
57572 }
57573 
Serialize(::protozero::Message * msg) const57574 void EnableTracingResponse::Serialize(::protozero::Message* msg) const {
57575   // Field 1: disabled
57576   if (_has_field_[1]) {
57577     msg->AppendTinyVarInt(1, disabled_);
57578   }
57579 
57580   // Field 3: error
57581   if (_has_field_[3]) {
57582     msg->AppendString(3, error_);
57583   }
57584 
57585   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
57586 }
57587 
57588 
57589 EnableTracingRequest::EnableTracingRequest() = default;
57590 EnableTracingRequest::~EnableTracingRequest() = default;
57591 EnableTracingRequest::EnableTracingRequest(const EnableTracingRequest&) = default;
57592 EnableTracingRequest& EnableTracingRequest::operator=(const EnableTracingRequest&) = default;
57593 EnableTracingRequest::EnableTracingRequest(EnableTracingRequest&&) noexcept = default;
57594 EnableTracingRequest& EnableTracingRequest::operator=(EnableTracingRequest&&) = default;
57595 
operator ==(const EnableTracingRequest & other) const57596 bool EnableTracingRequest::operator==(const EnableTracingRequest& other) const {
57597   return unknown_fields_ == other.unknown_fields_
57598    && trace_config_ == other.trace_config_
57599    && attach_notification_only_ == other.attach_notification_only_;
57600 }
57601 
ParseFromArray(const void * raw,size_t size)57602 bool EnableTracingRequest::ParseFromArray(const void* raw, size_t size) {
57603   unknown_fields_.clear();
57604   bool packed_error = false;
57605 
57606   ::protozero::ProtoDecoder dec(raw, size);
57607   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
57608     if (field.id() < _has_field_.size()) {
57609       _has_field_.set(field.id());
57610     }
57611     switch (field.id()) {
57612       case 1 /* trace_config */:
57613         (*trace_config_).ParseFromArray(field.data(), field.size());
57614         break;
57615       case 2 /* attach_notification_only */:
57616         field.get(&attach_notification_only_);
57617         break;
57618       default:
57619         field.SerializeAndAppendTo(&unknown_fields_);
57620         break;
57621     }
57622   }
57623   return !packed_error && !dec.bytes_left();
57624 }
57625 
SerializeAsString() const57626 std::string EnableTracingRequest::SerializeAsString() const {
57627   ::protozero::HeapBuffered<::protozero::Message> msg;
57628   Serialize(msg.get());
57629   return msg.SerializeAsString();
57630 }
57631 
SerializeAsArray() const57632 std::vector<uint8_t> EnableTracingRequest::SerializeAsArray() const {
57633   ::protozero::HeapBuffered<::protozero::Message> msg;
57634   Serialize(msg.get());
57635   return msg.SerializeAsArray();
57636 }
57637 
Serialize(::protozero::Message * msg) const57638 void EnableTracingRequest::Serialize(::protozero::Message* msg) const {
57639   // Field 1: trace_config
57640   if (_has_field_[1]) {
57641     (*trace_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
57642   }
57643 
57644   // Field 2: attach_notification_only
57645   if (_has_field_[2]) {
57646     msg->AppendTinyVarInt(2, attach_notification_only_);
57647   }
57648 
57649   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
57650 }
57651 
57652 }  // namespace perfetto
57653 }  // namespace protos
57654 }  // namespace gen
57655 #if defined(__GNUC__) || defined(__clang__)
57656 #pragma GCC diagnostic pop
57657 #endif
57658 // gen_amalgamated begin source: gen/protos/perfetto/ipc/producer_port.gen.cc
57659 // gen_amalgamated begin header: gen/protos/perfetto/ipc/producer_port.gen.h
57660 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
57661 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_PRODUCER_PORT_PROTO_CPP_H_
57662 #define PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_PRODUCER_PORT_PROTO_CPP_H_
57663 
57664 #include <stdint.h>
57665 #include <bitset>
57666 #include <vector>
57667 #include <string>
57668 #include <type_traits>
57669 
57670 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
57671 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
57672 // gen_amalgamated expanded: #include "perfetto/base/export.h"
57673 
57674 namespace perfetto {
57675 namespace protos {
57676 namespace gen {
57677 class SyncResponse;
57678 class SyncRequest;
57679 class GetAsyncCommandResponse;
57680 class GetAsyncCommandResponse_ClearIncrementalState;
57681 class GetAsyncCommandResponse_Flush;
57682 class GetAsyncCommandResponse_StopDataSource;
57683 class GetAsyncCommandResponse_StartDataSource;
57684 class DataSourceConfig;
57685 class TestConfig;
57686 class TestConfig_DummyFields;
57687 class InterceptorConfig;
57688 class ChromeConfig;
57689 class GetAsyncCommandResponse_SetupDataSource;
57690 class GetAsyncCommandResponse_SetupTracing;
57691 class GetAsyncCommandRequest;
57692 class ActivateTriggersResponse;
57693 class ActivateTriggersRequest;
57694 class NotifyDataSourceStoppedResponse;
57695 class NotifyDataSourceStoppedRequest;
57696 class NotifyDataSourceStartedResponse;
57697 class NotifyDataSourceStartedRequest;
57698 class CommitDataResponse;
57699 class UnregisterTraceWriterResponse;
57700 class UnregisterTraceWriterRequest;
57701 class RegisterTraceWriterResponse;
57702 class RegisterTraceWriterRequest;
57703 class UnregisterDataSourceResponse;
57704 class UnregisterDataSourceRequest;
57705 class RegisterDataSourceResponse;
57706 class RegisterDataSourceRequest;
57707 class DataSourceDescriptor;
57708 class InitializeConnectionResponse;
57709 class InitializeConnectionRequest;
57710 enum DataSourceConfig_SessionInitiator : int;
57711 enum ChromeConfig_ClientPriority : int;
57712 enum InitializeConnectionRequest_ProducerSMBScrapingMode : int;
57713 enum InitializeConnectionRequest_ProducerBuildFlags : int;
57714 }  // namespace perfetto
57715 }  // namespace protos
57716 }  // namespace gen
57717 
57718 namespace protozero {
57719 class Message;
57720 }  // namespace protozero
57721 
57722 namespace perfetto {
57723 namespace protos {
57724 namespace gen {
57725 enum InitializeConnectionRequest_ProducerSMBScrapingMode : int {
57726   InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_UNSPECIFIED = 0,
57727   InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_ENABLED = 1,
57728   InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_DISABLED = 2,
57729 };
57730 enum InitializeConnectionRequest_ProducerBuildFlags : int {
57731   InitializeConnectionRequest_ProducerBuildFlags_BUILD_FLAGS_UNSPECIFIED = 0,
57732   InitializeConnectionRequest_ProducerBuildFlags_BUILD_FLAGS_DCHECKS_ON = 1,
57733   InitializeConnectionRequest_ProducerBuildFlags_BUILD_FLAGS_DCHECKS_OFF = 2,
57734 };
57735 
57736 class PERFETTO_EXPORT SyncResponse : public ::protozero::CppMessageObj {
57737  public:
57738   enum FieldNumbers {
57739   };
57740 
57741   SyncResponse();
57742   ~SyncResponse() override;
57743   SyncResponse(SyncResponse&&) noexcept;
57744   SyncResponse& operator=(SyncResponse&&);
57745   SyncResponse(const SyncResponse&);
57746   SyncResponse& operator=(const SyncResponse&);
57747   bool operator==(const SyncResponse&) const;
operator !=(const SyncResponse & other) const57748   bool operator!=(const SyncResponse& other) const { return !(*this == other); }
57749 
57750   bool ParseFromArray(const void*, size_t) override;
57751   std::string SerializeAsString() const override;
57752   std::vector<uint8_t> SerializeAsArray() const override;
57753   void Serialize(::protozero::Message*) const;
57754 
57755  private:
57756 
57757   // Allows to preserve unknown protobuf fields for compatibility
57758   // with future versions of .proto files.
57759   std::string unknown_fields_;
57760 
57761   std::bitset<2> _has_field_{};
57762 };
57763 
57764 
57765 class PERFETTO_EXPORT SyncRequest : public ::protozero::CppMessageObj {
57766  public:
57767   enum FieldNumbers {
57768   };
57769 
57770   SyncRequest();
57771   ~SyncRequest() override;
57772   SyncRequest(SyncRequest&&) noexcept;
57773   SyncRequest& operator=(SyncRequest&&);
57774   SyncRequest(const SyncRequest&);
57775   SyncRequest& operator=(const SyncRequest&);
57776   bool operator==(const SyncRequest&) const;
operator !=(const SyncRequest & other) const57777   bool operator!=(const SyncRequest& other) const { return !(*this == other); }
57778 
57779   bool ParseFromArray(const void*, size_t) override;
57780   std::string SerializeAsString() const override;
57781   std::vector<uint8_t> SerializeAsArray() const override;
57782   void Serialize(::protozero::Message*) const;
57783 
57784  private:
57785 
57786   // Allows to preserve unknown protobuf fields for compatibility
57787   // with future versions of .proto files.
57788   std::string unknown_fields_;
57789 
57790   std::bitset<2> _has_field_{};
57791 };
57792 
57793 
57794 class PERFETTO_EXPORT GetAsyncCommandResponse : public ::protozero::CppMessageObj {
57795  public:
57796   using SetupDataSource = GetAsyncCommandResponse_SetupDataSource;
57797   using StartDataSource = GetAsyncCommandResponse_StartDataSource;
57798   using StopDataSource = GetAsyncCommandResponse_StopDataSource;
57799   using SetupTracing = GetAsyncCommandResponse_SetupTracing;
57800   using Flush = GetAsyncCommandResponse_Flush;
57801   using ClearIncrementalState = GetAsyncCommandResponse_ClearIncrementalState;
57802   enum FieldNumbers {
57803     kSetupTracingFieldNumber = 3,
57804     kSetupDataSourceFieldNumber = 6,
57805     kStartDataSourceFieldNumber = 1,
57806     kStopDataSourceFieldNumber = 2,
57807     kFlushFieldNumber = 5,
57808     kClearIncrementalStateFieldNumber = 7,
57809   };
57810 
57811   GetAsyncCommandResponse();
57812   ~GetAsyncCommandResponse() override;
57813   GetAsyncCommandResponse(GetAsyncCommandResponse&&) noexcept;
57814   GetAsyncCommandResponse& operator=(GetAsyncCommandResponse&&);
57815   GetAsyncCommandResponse(const GetAsyncCommandResponse&);
57816   GetAsyncCommandResponse& operator=(const GetAsyncCommandResponse&);
57817   bool operator==(const GetAsyncCommandResponse&) const;
operator !=(const GetAsyncCommandResponse & other) const57818   bool operator!=(const GetAsyncCommandResponse& other) const { return !(*this == other); }
57819 
57820   bool ParseFromArray(const void*, size_t) override;
57821   std::string SerializeAsString() const override;
57822   std::vector<uint8_t> SerializeAsArray() const override;
57823   void Serialize(::protozero::Message*) const;
57824 
has_setup_tracing() const57825   bool has_setup_tracing() const { return _has_field_[3]; }
setup_tracing() const57826   const GetAsyncCommandResponse_SetupTracing& setup_tracing() const { return *setup_tracing_; }
mutable_setup_tracing()57827   GetAsyncCommandResponse_SetupTracing* mutable_setup_tracing() { _has_field_.set(3); return setup_tracing_.get(); }
57828 
has_setup_data_source() const57829   bool has_setup_data_source() const { return _has_field_[6]; }
setup_data_source() const57830   const GetAsyncCommandResponse_SetupDataSource& setup_data_source() const { return *setup_data_source_; }
mutable_setup_data_source()57831   GetAsyncCommandResponse_SetupDataSource* mutable_setup_data_source() { _has_field_.set(6); return setup_data_source_.get(); }
57832 
has_start_data_source() const57833   bool has_start_data_source() const { return _has_field_[1]; }
start_data_source() const57834   const GetAsyncCommandResponse_StartDataSource& start_data_source() const { return *start_data_source_; }
mutable_start_data_source()57835   GetAsyncCommandResponse_StartDataSource* mutable_start_data_source() { _has_field_.set(1); return start_data_source_.get(); }
57836 
has_stop_data_source() const57837   bool has_stop_data_source() const { return _has_field_[2]; }
stop_data_source() const57838   const GetAsyncCommandResponse_StopDataSource& stop_data_source() const { return *stop_data_source_; }
mutable_stop_data_source()57839   GetAsyncCommandResponse_StopDataSource* mutable_stop_data_source() { _has_field_.set(2); return stop_data_source_.get(); }
57840 
has_flush() const57841   bool has_flush() const { return _has_field_[5]; }
flush() const57842   const GetAsyncCommandResponse_Flush& flush() const { return *flush_; }
mutable_flush()57843   GetAsyncCommandResponse_Flush* mutable_flush() { _has_field_.set(5); return flush_.get(); }
57844 
has_clear_incremental_state() const57845   bool has_clear_incremental_state() const { return _has_field_[7]; }
clear_incremental_state() const57846   const GetAsyncCommandResponse_ClearIncrementalState& clear_incremental_state() const { return *clear_incremental_state_; }
mutable_clear_incremental_state()57847   GetAsyncCommandResponse_ClearIncrementalState* mutable_clear_incremental_state() { _has_field_.set(7); return clear_incremental_state_.get(); }
57848 
57849  private:
57850   ::protozero::CopyablePtr<GetAsyncCommandResponse_SetupTracing> setup_tracing_;
57851   ::protozero::CopyablePtr<GetAsyncCommandResponse_SetupDataSource> setup_data_source_;
57852   ::protozero::CopyablePtr<GetAsyncCommandResponse_StartDataSource> start_data_source_;
57853   ::protozero::CopyablePtr<GetAsyncCommandResponse_StopDataSource> stop_data_source_;
57854   ::protozero::CopyablePtr<GetAsyncCommandResponse_Flush> flush_;
57855   ::protozero::CopyablePtr<GetAsyncCommandResponse_ClearIncrementalState> clear_incremental_state_;
57856 
57857   // Allows to preserve unknown protobuf fields for compatibility
57858   // with future versions of .proto files.
57859   std::string unknown_fields_;
57860 
57861   std::bitset<8> _has_field_{};
57862 };
57863 
57864 
57865 class PERFETTO_EXPORT GetAsyncCommandResponse_ClearIncrementalState : public ::protozero::CppMessageObj {
57866  public:
57867   enum FieldNumbers {
57868     kDataSourceIdsFieldNumber = 1,
57869   };
57870 
57871   GetAsyncCommandResponse_ClearIncrementalState();
57872   ~GetAsyncCommandResponse_ClearIncrementalState() override;
57873   GetAsyncCommandResponse_ClearIncrementalState(GetAsyncCommandResponse_ClearIncrementalState&&) noexcept;
57874   GetAsyncCommandResponse_ClearIncrementalState& operator=(GetAsyncCommandResponse_ClearIncrementalState&&);
57875   GetAsyncCommandResponse_ClearIncrementalState(const GetAsyncCommandResponse_ClearIncrementalState&);
57876   GetAsyncCommandResponse_ClearIncrementalState& operator=(const GetAsyncCommandResponse_ClearIncrementalState&);
57877   bool operator==(const GetAsyncCommandResponse_ClearIncrementalState&) const;
operator !=(const GetAsyncCommandResponse_ClearIncrementalState & other) const57878   bool operator!=(const GetAsyncCommandResponse_ClearIncrementalState& other) const { return !(*this == other); }
57879 
57880   bool ParseFromArray(const void*, size_t) override;
57881   std::string SerializeAsString() const override;
57882   std::vector<uint8_t> SerializeAsArray() const override;
57883   void Serialize(::protozero::Message*) const;
57884 
data_source_ids() const57885   const std::vector<uint64_t>& data_source_ids() const { return data_source_ids_; }
mutable_data_source_ids()57886   std::vector<uint64_t>* mutable_data_source_ids() { return &data_source_ids_; }
data_source_ids_size() const57887   int data_source_ids_size() const { return static_cast<int>(data_source_ids_.size()); }
clear_data_source_ids()57888   void clear_data_source_ids() { data_source_ids_.clear(); }
add_data_source_ids(uint64_t value)57889   void add_data_source_ids(uint64_t value) { data_source_ids_.emplace_back(value); }
add_data_source_ids()57890   uint64_t* add_data_source_ids() { data_source_ids_.emplace_back(); return &data_source_ids_.back(); }
57891 
57892  private:
57893   std::vector<uint64_t> data_source_ids_;
57894 
57895   // Allows to preserve unknown protobuf fields for compatibility
57896   // with future versions of .proto files.
57897   std::string unknown_fields_;
57898 
57899   std::bitset<2> _has_field_{};
57900 };
57901 
57902 
57903 class PERFETTO_EXPORT GetAsyncCommandResponse_Flush : public ::protozero::CppMessageObj {
57904  public:
57905   enum FieldNumbers {
57906     kDataSourceIdsFieldNumber = 1,
57907     kRequestIdFieldNumber = 2,
57908   };
57909 
57910   GetAsyncCommandResponse_Flush();
57911   ~GetAsyncCommandResponse_Flush() override;
57912   GetAsyncCommandResponse_Flush(GetAsyncCommandResponse_Flush&&) noexcept;
57913   GetAsyncCommandResponse_Flush& operator=(GetAsyncCommandResponse_Flush&&);
57914   GetAsyncCommandResponse_Flush(const GetAsyncCommandResponse_Flush&);
57915   GetAsyncCommandResponse_Flush& operator=(const GetAsyncCommandResponse_Flush&);
57916   bool operator==(const GetAsyncCommandResponse_Flush&) const;
operator !=(const GetAsyncCommandResponse_Flush & other) const57917   bool operator!=(const GetAsyncCommandResponse_Flush& other) const { return !(*this == other); }
57918 
57919   bool ParseFromArray(const void*, size_t) override;
57920   std::string SerializeAsString() const override;
57921   std::vector<uint8_t> SerializeAsArray() const override;
57922   void Serialize(::protozero::Message*) const;
57923 
data_source_ids() const57924   const std::vector<uint64_t>& data_source_ids() const { return data_source_ids_; }
mutable_data_source_ids()57925   std::vector<uint64_t>* mutable_data_source_ids() { return &data_source_ids_; }
data_source_ids_size() const57926   int data_source_ids_size() const { return static_cast<int>(data_source_ids_.size()); }
clear_data_source_ids()57927   void clear_data_source_ids() { data_source_ids_.clear(); }
add_data_source_ids(uint64_t value)57928   void add_data_source_ids(uint64_t value) { data_source_ids_.emplace_back(value); }
add_data_source_ids()57929   uint64_t* add_data_source_ids() { data_source_ids_.emplace_back(); return &data_source_ids_.back(); }
57930 
has_request_id() const57931   bool has_request_id() const { return _has_field_[2]; }
request_id() const57932   uint64_t request_id() const { return request_id_; }
set_request_id(uint64_t value)57933   void set_request_id(uint64_t value) { request_id_ = value; _has_field_.set(2); }
57934 
57935  private:
57936   std::vector<uint64_t> data_source_ids_;
57937   uint64_t request_id_{};
57938 
57939   // Allows to preserve unknown protobuf fields for compatibility
57940   // with future versions of .proto files.
57941   std::string unknown_fields_;
57942 
57943   std::bitset<3> _has_field_{};
57944 };
57945 
57946 
57947 class PERFETTO_EXPORT GetAsyncCommandResponse_StopDataSource : public ::protozero::CppMessageObj {
57948  public:
57949   enum FieldNumbers {
57950     kInstanceIdFieldNumber = 1,
57951   };
57952 
57953   GetAsyncCommandResponse_StopDataSource();
57954   ~GetAsyncCommandResponse_StopDataSource() override;
57955   GetAsyncCommandResponse_StopDataSource(GetAsyncCommandResponse_StopDataSource&&) noexcept;
57956   GetAsyncCommandResponse_StopDataSource& operator=(GetAsyncCommandResponse_StopDataSource&&);
57957   GetAsyncCommandResponse_StopDataSource(const GetAsyncCommandResponse_StopDataSource&);
57958   GetAsyncCommandResponse_StopDataSource& operator=(const GetAsyncCommandResponse_StopDataSource&);
57959   bool operator==(const GetAsyncCommandResponse_StopDataSource&) const;
operator !=(const GetAsyncCommandResponse_StopDataSource & other) const57960   bool operator!=(const GetAsyncCommandResponse_StopDataSource& other) const { return !(*this == other); }
57961 
57962   bool ParseFromArray(const void*, size_t) override;
57963   std::string SerializeAsString() const override;
57964   std::vector<uint8_t> SerializeAsArray() const override;
57965   void Serialize(::protozero::Message*) const;
57966 
has_instance_id() const57967   bool has_instance_id() const { return _has_field_[1]; }
instance_id() const57968   uint64_t instance_id() const { return instance_id_; }
set_instance_id(uint64_t value)57969   void set_instance_id(uint64_t value) { instance_id_ = value; _has_field_.set(1); }
57970 
57971  private:
57972   uint64_t instance_id_{};
57973 
57974   // Allows to preserve unknown protobuf fields for compatibility
57975   // with future versions of .proto files.
57976   std::string unknown_fields_;
57977 
57978   std::bitset<2> _has_field_{};
57979 };
57980 
57981 
57982 class PERFETTO_EXPORT GetAsyncCommandResponse_StartDataSource : public ::protozero::CppMessageObj {
57983  public:
57984   enum FieldNumbers {
57985     kNewInstanceIdFieldNumber = 1,
57986     kConfigFieldNumber = 2,
57987   };
57988 
57989   GetAsyncCommandResponse_StartDataSource();
57990   ~GetAsyncCommandResponse_StartDataSource() override;
57991   GetAsyncCommandResponse_StartDataSource(GetAsyncCommandResponse_StartDataSource&&) noexcept;
57992   GetAsyncCommandResponse_StartDataSource& operator=(GetAsyncCommandResponse_StartDataSource&&);
57993   GetAsyncCommandResponse_StartDataSource(const GetAsyncCommandResponse_StartDataSource&);
57994   GetAsyncCommandResponse_StartDataSource& operator=(const GetAsyncCommandResponse_StartDataSource&);
57995   bool operator==(const GetAsyncCommandResponse_StartDataSource&) const;
operator !=(const GetAsyncCommandResponse_StartDataSource & other) const57996   bool operator!=(const GetAsyncCommandResponse_StartDataSource& other) const { return !(*this == other); }
57997 
57998   bool ParseFromArray(const void*, size_t) override;
57999   std::string SerializeAsString() const override;
58000   std::vector<uint8_t> SerializeAsArray() const override;
58001   void Serialize(::protozero::Message*) const;
58002 
has_new_instance_id() const58003   bool has_new_instance_id() const { return _has_field_[1]; }
new_instance_id() const58004   uint64_t new_instance_id() const { return new_instance_id_; }
set_new_instance_id(uint64_t value)58005   void set_new_instance_id(uint64_t value) { new_instance_id_ = value; _has_field_.set(1); }
58006 
has_config() const58007   bool has_config() const { return _has_field_[2]; }
config() const58008   const DataSourceConfig& config() const { return *config_; }
mutable_config()58009   DataSourceConfig* mutable_config() { _has_field_.set(2); return config_.get(); }
58010 
58011  private:
58012   uint64_t new_instance_id_{};
58013   ::protozero::CopyablePtr<DataSourceConfig> config_;
58014 
58015   // Allows to preserve unknown protobuf fields for compatibility
58016   // with future versions of .proto files.
58017   std::string unknown_fields_;
58018 
58019   std::bitset<3> _has_field_{};
58020 };
58021 
58022 
58023 class PERFETTO_EXPORT GetAsyncCommandResponse_SetupDataSource : public ::protozero::CppMessageObj {
58024  public:
58025   enum FieldNumbers {
58026     kNewInstanceIdFieldNumber = 1,
58027     kConfigFieldNumber = 2,
58028   };
58029 
58030   GetAsyncCommandResponse_SetupDataSource();
58031   ~GetAsyncCommandResponse_SetupDataSource() override;
58032   GetAsyncCommandResponse_SetupDataSource(GetAsyncCommandResponse_SetupDataSource&&) noexcept;
58033   GetAsyncCommandResponse_SetupDataSource& operator=(GetAsyncCommandResponse_SetupDataSource&&);
58034   GetAsyncCommandResponse_SetupDataSource(const GetAsyncCommandResponse_SetupDataSource&);
58035   GetAsyncCommandResponse_SetupDataSource& operator=(const GetAsyncCommandResponse_SetupDataSource&);
58036   bool operator==(const GetAsyncCommandResponse_SetupDataSource&) const;
operator !=(const GetAsyncCommandResponse_SetupDataSource & other) const58037   bool operator!=(const GetAsyncCommandResponse_SetupDataSource& other) const { return !(*this == other); }
58038 
58039   bool ParseFromArray(const void*, size_t) override;
58040   std::string SerializeAsString() const override;
58041   std::vector<uint8_t> SerializeAsArray() const override;
58042   void Serialize(::protozero::Message*) const;
58043 
has_new_instance_id() const58044   bool has_new_instance_id() const { return _has_field_[1]; }
new_instance_id() const58045   uint64_t new_instance_id() const { return new_instance_id_; }
set_new_instance_id(uint64_t value)58046   void set_new_instance_id(uint64_t value) { new_instance_id_ = value; _has_field_.set(1); }
58047 
has_config() const58048   bool has_config() const { return _has_field_[2]; }
config() const58049   const DataSourceConfig& config() const { return *config_; }
mutable_config()58050   DataSourceConfig* mutable_config() { _has_field_.set(2); return config_.get(); }
58051 
58052  private:
58053   uint64_t new_instance_id_{};
58054   ::protozero::CopyablePtr<DataSourceConfig> config_;
58055 
58056   // Allows to preserve unknown protobuf fields for compatibility
58057   // with future versions of .proto files.
58058   std::string unknown_fields_;
58059 
58060   std::bitset<3> _has_field_{};
58061 };
58062 
58063 
58064 class PERFETTO_EXPORT GetAsyncCommandResponse_SetupTracing : public ::protozero::CppMessageObj {
58065  public:
58066   enum FieldNumbers {
58067     kSharedBufferPageSizeKbFieldNumber = 1,
58068   };
58069 
58070   GetAsyncCommandResponse_SetupTracing();
58071   ~GetAsyncCommandResponse_SetupTracing() override;
58072   GetAsyncCommandResponse_SetupTracing(GetAsyncCommandResponse_SetupTracing&&) noexcept;
58073   GetAsyncCommandResponse_SetupTracing& operator=(GetAsyncCommandResponse_SetupTracing&&);
58074   GetAsyncCommandResponse_SetupTracing(const GetAsyncCommandResponse_SetupTracing&);
58075   GetAsyncCommandResponse_SetupTracing& operator=(const GetAsyncCommandResponse_SetupTracing&);
58076   bool operator==(const GetAsyncCommandResponse_SetupTracing&) const;
operator !=(const GetAsyncCommandResponse_SetupTracing & other) const58077   bool operator!=(const GetAsyncCommandResponse_SetupTracing& other) const { return !(*this == other); }
58078 
58079   bool ParseFromArray(const void*, size_t) override;
58080   std::string SerializeAsString() const override;
58081   std::vector<uint8_t> SerializeAsArray() const override;
58082   void Serialize(::protozero::Message*) const;
58083 
has_shared_buffer_page_size_kb() const58084   bool has_shared_buffer_page_size_kb() const { return _has_field_[1]; }
shared_buffer_page_size_kb() const58085   uint32_t shared_buffer_page_size_kb() const { return shared_buffer_page_size_kb_; }
set_shared_buffer_page_size_kb(uint32_t value)58086   void set_shared_buffer_page_size_kb(uint32_t value) { shared_buffer_page_size_kb_ = value; _has_field_.set(1); }
58087 
58088  private:
58089   uint32_t shared_buffer_page_size_kb_{};
58090 
58091   // Allows to preserve unknown protobuf fields for compatibility
58092   // with future versions of .proto files.
58093   std::string unknown_fields_;
58094 
58095   std::bitset<2> _has_field_{};
58096 };
58097 
58098 
58099 class PERFETTO_EXPORT GetAsyncCommandRequest : public ::protozero::CppMessageObj {
58100  public:
58101   enum FieldNumbers {
58102   };
58103 
58104   GetAsyncCommandRequest();
58105   ~GetAsyncCommandRequest() override;
58106   GetAsyncCommandRequest(GetAsyncCommandRequest&&) noexcept;
58107   GetAsyncCommandRequest& operator=(GetAsyncCommandRequest&&);
58108   GetAsyncCommandRequest(const GetAsyncCommandRequest&);
58109   GetAsyncCommandRequest& operator=(const GetAsyncCommandRequest&);
58110   bool operator==(const GetAsyncCommandRequest&) const;
operator !=(const GetAsyncCommandRequest & other) const58111   bool operator!=(const GetAsyncCommandRequest& other) const { return !(*this == other); }
58112 
58113   bool ParseFromArray(const void*, size_t) override;
58114   std::string SerializeAsString() const override;
58115   std::vector<uint8_t> SerializeAsArray() const override;
58116   void Serialize(::protozero::Message*) const;
58117 
58118  private:
58119 
58120   // Allows to preserve unknown protobuf fields for compatibility
58121   // with future versions of .proto files.
58122   std::string unknown_fields_;
58123 
58124   std::bitset<2> _has_field_{};
58125 };
58126 
58127 
58128 class PERFETTO_EXPORT ActivateTriggersResponse : public ::protozero::CppMessageObj {
58129  public:
58130   enum FieldNumbers {
58131   };
58132 
58133   ActivateTriggersResponse();
58134   ~ActivateTriggersResponse() override;
58135   ActivateTriggersResponse(ActivateTriggersResponse&&) noexcept;
58136   ActivateTriggersResponse& operator=(ActivateTriggersResponse&&);
58137   ActivateTriggersResponse(const ActivateTriggersResponse&);
58138   ActivateTriggersResponse& operator=(const ActivateTriggersResponse&);
58139   bool operator==(const ActivateTriggersResponse&) const;
operator !=(const ActivateTriggersResponse & other) const58140   bool operator!=(const ActivateTriggersResponse& other) const { return !(*this == other); }
58141 
58142   bool ParseFromArray(const void*, size_t) override;
58143   std::string SerializeAsString() const override;
58144   std::vector<uint8_t> SerializeAsArray() const override;
58145   void Serialize(::protozero::Message*) const;
58146 
58147  private:
58148 
58149   // Allows to preserve unknown protobuf fields for compatibility
58150   // with future versions of .proto files.
58151   std::string unknown_fields_;
58152 
58153   std::bitset<2> _has_field_{};
58154 };
58155 
58156 
58157 class PERFETTO_EXPORT ActivateTriggersRequest : public ::protozero::CppMessageObj {
58158  public:
58159   enum FieldNumbers {
58160     kTriggerNamesFieldNumber = 1,
58161   };
58162 
58163   ActivateTriggersRequest();
58164   ~ActivateTriggersRequest() override;
58165   ActivateTriggersRequest(ActivateTriggersRequest&&) noexcept;
58166   ActivateTriggersRequest& operator=(ActivateTriggersRequest&&);
58167   ActivateTriggersRequest(const ActivateTriggersRequest&);
58168   ActivateTriggersRequest& operator=(const ActivateTriggersRequest&);
58169   bool operator==(const ActivateTriggersRequest&) const;
operator !=(const ActivateTriggersRequest & other) const58170   bool operator!=(const ActivateTriggersRequest& other) const { return !(*this == other); }
58171 
58172   bool ParseFromArray(const void*, size_t) override;
58173   std::string SerializeAsString() const override;
58174   std::vector<uint8_t> SerializeAsArray() const override;
58175   void Serialize(::protozero::Message*) const;
58176 
trigger_names() const58177   const std::vector<std::string>& trigger_names() const { return trigger_names_; }
mutable_trigger_names()58178   std::vector<std::string>* mutable_trigger_names() { return &trigger_names_; }
trigger_names_size() const58179   int trigger_names_size() const { return static_cast<int>(trigger_names_.size()); }
clear_trigger_names()58180   void clear_trigger_names() { trigger_names_.clear(); }
add_trigger_names(std::string value)58181   void add_trigger_names(std::string value) { trigger_names_.emplace_back(value); }
add_trigger_names()58182   std::string* add_trigger_names() { trigger_names_.emplace_back(); return &trigger_names_.back(); }
58183 
58184  private:
58185   std::vector<std::string> trigger_names_;
58186 
58187   // Allows to preserve unknown protobuf fields for compatibility
58188   // with future versions of .proto files.
58189   std::string unknown_fields_;
58190 
58191   std::bitset<2> _has_field_{};
58192 };
58193 
58194 
58195 class PERFETTO_EXPORT NotifyDataSourceStoppedResponse : public ::protozero::CppMessageObj {
58196  public:
58197   enum FieldNumbers {
58198   };
58199 
58200   NotifyDataSourceStoppedResponse();
58201   ~NotifyDataSourceStoppedResponse() override;
58202   NotifyDataSourceStoppedResponse(NotifyDataSourceStoppedResponse&&) noexcept;
58203   NotifyDataSourceStoppedResponse& operator=(NotifyDataSourceStoppedResponse&&);
58204   NotifyDataSourceStoppedResponse(const NotifyDataSourceStoppedResponse&);
58205   NotifyDataSourceStoppedResponse& operator=(const NotifyDataSourceStoppedResponse&);
58206   bool operator==(const NotifyDataSourceStoppedResponse&) const;
operator !=(const NotifyDataSourceStoppedResponse & other) const58207   bool operator!=(const NotifyDataSourceStoppedResponse& other) const { return !(*this == other); }
58208 
58209   bool ParseFromArray(const void*, size_t) override;
58210   std::string SerializeAsString() const override;
58211   std::vector<uint8_t> SerializeAsArray() const override;
58212   void Serialize(::protozero::Message*) const;
58213 
58214  private:
58215 
58216   // Allows to preserve unknown protobuf fields for compatibility
58217   // with future versions of .proto files.
58218   std::string unknown_fields_;
58219 
58220   std::bitset<2> _has_field_{};
58221 };
58222 
58223 
58224 class PERFETTO_EXPORT NotifyDataSourceStoppedRequest : public ::protozero::CppMessageObj {
58225  public:
58226   enum FieldNumbers {
58227     kDataSourceIdFieldNumber = 1,
58228   };
58229 
58230   NotifyDataSourceStoppedRequest();
58231   ~NotifyDataSourceStoppedRequest() override;
58232   NotifyDataSourceStoppedRequest(NotifyDataSourceStoppedRequest&&) noexcept;
58233   NotifyDataSourceStoppedRequest& operator=(NotifyDataSourceStoppedRequest&&);
58234   NotifyDataSourceStoppedRequest(const NotifyDataSourceStoppedRequest&);
58235   NotifyDataSourceStoppedRequest& operator=(const NotifyDataSourceStoppedRequest&);
58236   bool operator==(const NotifyDataSourceStoppedRequest&) const;
operator !=(const NotifyDataSourceStoppedRequest & other) const58237   bool operator!=(const NotifyDataSourceStoppedRequest& other) const { return !(*this == other); }
58238 
58239   bool ParseFromArray(const void*, size_t) override;
58240   std::string SerializeAsString() const override;
58241   std::vector<uint8_t> SerializeAsArray() const override;
58242   void Serialize(::protozero::Message*) const;
58243 
has_data_source_id() const58244   bool has_data_source_id() const { return _has_field_[1]; }
data_source_id() const58245   uint64_t data_source_id() const { return data_source_id_; }
set_data_source_id(uint64_t value)58246   void set_data_source_id(uint64_t value) { data_source_id_ = value; _has_field_.set(1); }
58247 
58248  private:
58249   uint64_t data_source_id_{};
58250 
58251   // Allows to preserve unknown protobuf fields for compatibility
58252   // with future versions of .proto files.
58253   std::string unknown_fields_;
58254 
58255   std::bitset<2> _has_field_{};
58256 };
58257 
58258 
58259 class PERFETTO_EXPORT NotifyDataSourceStartedResponse : public ::protozero::CppMessageObj {
58260  public:
58261   enum FieldNumbers {
58262   };
58263 
58264   NotifyDataSourceStartedResponse();
58265   ~NotifyDataSourceStartedResponse() override;
58266   NotifyDataSourceStartedResponse(NotifyDataSourceStartedResponse&&) noexcept;
58267   NotifyDataSourceStartedResponse& operator=(NotifyDataSourceStartedResponse&&);
58268   NotifyDataSourceStartedResponse(const NotifyDataSourceStartedResponse&);
58269   NotifyDataSourceStartedResponse& operator=(const NotifyDataSourceStartedResponse&);
58270   bool operator==(const NotifyDataSourceStartedResponse&) const;
operator !=(const NotifyDataSourceStartedResponse & other) const58271   bool operator!=(const NotifyDataSourceStartedResponse& other) const { return !(*this == other); }
58272 
58273   bool ParseFromArray(const void*, size_t) override;
58274   std::string SerializeAsString() const override;
58275   std::vector<uint8_t> SerializeAsArray() const override;
58276   void Serialize(::protozero::Message*) const;
58277 
58278  private:
58279 
58280   // Allows to preserve unknown protobuf fields for compatibility
58281   // with future versions of .proto files.
58282   std::string unknown_fields_;
58283 
58284   std::bitset<2> _has_field_{};
58285 };
58286 
58287 
58288 class PERFETTO_EXPORT NotifyDataSourceStartedRequest : public ::protozero::CppMessageObj {
58289  public:
58290   enum FieldNumbers {
58291     kDataSourceIdFieldNumber = 1,
58292   };
58293 
58294   NotifyDataSourceStartedRequest();
58295   ~NotifyDataSourceStartedRequest() override;
58296   NotifyDataSourceStartedRequest(NotifyDataSourceStartedRequest&&) noexcept;
58297   NotifyDataSourceStartedRequest& operator=(NotifyDataSourceStartedRequest&&);
58298   NotifyDataSourceStartedRequest(const NotifyDataSourceStartedRequest&);
58299   NotifyDataSourceStartedRequest& operator=(const NotifyDataSourceStartedRequest&);
58300   bool operator==(const NotifyDataSourceStartedRequest&) const;
operator !=(const NotifyDataSourceStartedRequest & other) const58301   bool operator!=(const NotifyDataSourceStartedRequest& other) const { return !(*this == other); }
58302 
58303   bool ParseFromArray(const void*, size_t) override;
58304   std::string SerializeAsString() const override;
58305   std::vector<uint8_t> SerializeAsArray() const override;
58306   void Serialize(::protozero::Message*) const;
58307 
has_data_source_id() const58308   bool has_data_source_id() const { return _has_field_[1]; }
data_source_id() const58309   uint64_t data_source_id() const { return data_source_id_; }
set_data_source_id(uint64_t value)58310   void set_data_source_id(uint64_t value) { data_source_id_ = value; _has_field_.set(1); }
58311 
58312  private:
58313   uint64_t data_source_id_{};
58314 
58315   // Allows to preserve unknown protobuf fields for compatibility
58316   // with future versions of .proto files.
58317   std::string unknown_fields_;
58318 
58319   std::bitset<2> _has_field_{};
58320 };
58321 
58322 
58323 class PERFETTO_EXPORT CommitDataResponse : public ::protozero::CppMessageObj {
58324  public:
58325   enum FieldNumbers {
58326   };
58327 
58328   CommitDataResponse();
58329   ~CommitDataResponse() override;
58330   CommitDataResponse(CommitDataResponse&&) noexcept;
58331   CommitDataResponse& operator=(CommitDataResponse&&);
58332   CommitDataResponse(const CommitDataResponse&);
58333   CommitDataResponse& operator=(const CommitDataResponse&);
58334   bool operator==(const CommitDataResponse&) const;
operator !=(const CommitDataResponse & other) const58335   bool operator!=(const CommitDataResponse& other) const { return !(*this == other); }
58336 
58337   bool ParseFromArray(const void*, size_t) override;
58338   std::string SerializeAsString() const override;
58339   std::vector<uint8_t> SerializeAsArray() const override;
58340   void Serialize(::protozero::Message*) const;
58341 
58342  private:
58343 
58344   // Allows to preserve unknown protobuf fields for compatibility
58345   // with future versions of .proto files.
58346   std::string unknown_fields_;
58347 
58348   std::bitset<2> _has_field_{};
58349 };
58350 
58351 
58352 class PERFETTO_EXPORT UnregisterTraceWriterResponse : public ::protozero::CppMessageObj {
58353  public:
58354   enum FieldNumbers {
58355   };
58356 
58357   UnregisterTraceWriterResponse();
58358   ~UnregisterTraceWriterResponse() override;
58359   UnregisterTraceWriterResponse(UnregisterTraceWriterResponse&&) noexcept;
58360   UnregisterTraceWriterResponse& operator=(UnregisterTraceWriterResponse&&);
58361   UnregisterTraceWriterResponse(const UnregisterTraceWriterResponse&);
58362   UnregisterTraceWriterResponse& operator=(const UnregisterTraceWriterResponse&);
58363   bool operator==(const UnregisterTraceWriterResponse&) const;
operator !=(const UnregisterTraceWriterResponse & other) const58364   bool operator!=(const UnregisterTraceWriterResponse& other) const { return !(*this == other); }
58365 
58366   bool ParseFromArray(const void*, size_t) override;
58367   std::string SerializeAsString() const override;
58368   std::vector<uint8_t> SerializeAsArray() const override;
58369   void Serialize(::protozero::Message*) const;
58370 
58371  private:
58372 
58373   // Allows to preserve unknown protobuf fields for compatibility
58374   // with future versions of .proto files.
58375   std::string unknown_fields_;
58376 
58377   std::bitset<2> _has_field_{};
58378 };
58379 
58380 
58381 class PERFETTO_EXPORT UnregisterTraceWriterRequest : public ::protozero::CppMessageObj {
58382  public:
58383   enum FieldNumbers {
58384     kTraceWriterIdFieldNumber = 1,
58385   };
58386 
58387   UnregisterTraceWriterRequest();
58388   ~UnregisterTraceWriterRequest() override;
58389   UnregisterTraceWriterRequest(UnregisterTraceWriterRequest&&) noexcept;
58390   UnregisterTraceWriterRequest& operator=(UnregisterTraceWriterRequest&&);
58391   UnregisterTraceWriterRequest(const UnregisterTraceWriterRequest&);
58392   UnregisterTraceWriterRequest& operator=(const UnregisterTraceWriterRequest&);
58393   bool operator==(const UnregisterTraceWriterRequest&) const;
operator !=(const UnregisterTraceWriterRequest & other) const58394   bool operator!=(const UnregisterTraceWriterRequest& other) const { return !(*this == other); }
58395 
58396   bool ParseFromArray(const void*, size_t) override;
58397   std::string SerializeAsString() const override;
58398   std::vector<uint8_t> SerializeAsArray() const override;
58399   void Serialize(::protozero::Message*) const;
58400 
has_trace_writer_id() const58401   bool has_trace_writer_id() const { return _has_field_[1]; }
trace_writer_id() const58402   uint32_t trace_writer_id() const { return trace_writer_id_; }
set_trace_writer_id(uint32_t value)58403   void set_trace_writer_id(uint32_t value) { trace_writer_id_ = value; _has_field_.set(1); }
58404 
58405  private:
58406   uint32_t trace_writer_id_{};
58407 
58408   // Allows to preserve unknown protobuf fields for compatibility
58409   // with future versions of .proto files.
58410   std::string unknown_fields_;
58411 
58412   std::bitset<2> _has_field_{};
58413 };
58414 
58415 
58416 class PERFETTO_EXPORT RegisterTraceWriterResponse : public ::protozero::CppMessageObj {
58417  public:
58418   enum FieldNumbers {
58419   };
58420 
58421   RegisterTraceWriterResponse();
58422   ~RegisterTraceWriterResponse() override;
58423   RegisterTraceWriterResponse(RegisterTraceWriterResponse&&) noexcept;
58424   RegisterTraceWriterResponse& operator=(RegisterTraceWriterResponse&&);
58425   RegisterTraceWriterResponse(const RegisterTraceWriterResponse&);
58426   RegisterTraceWriterResponse& operator=(const RegisterTraceWriterResponse&);
58427   bool operator==(const RegisterTraceWriterResponse&) const;
operator !=(const RegisterTraceWriterResponse & other) const58428   bool operator!=(const RegisterTraceWriterResponse& other) const { return !(*this == other); }
58429 
58430   bool ParseFromArray(const void*, size_t) override;
58431   std::string SerializeAsString() const override;
58432   std::vector<uint8_t> SerializeAsArray() const override;
58433   void Serialize(::protozero::Message*) const;
58434 
58435  private:
58436 
58437   // Allows to preserve unknown protobuf fields for compatibility
58438   // with future versions of .proto files.
58439   std::string unknown_fields_;
58440 
58441   std::bitset<2> _has_field_{};
58442 };
58443 
58444 
58445 class PERFETTO_EXPORT RegisterTraceWriterRequest : public ::protozero::CppMessageObj {
58446  public:
58447   enum FieldNumbers {
58448     kTraceWriterIdFieldNumber = 1,
58449     kTargetBufferFieldNumber = 2,
58450   };
58451 
58452   RegisterTraceWriterRequest();
58453   ~RegisterTraceWriterRequest() override;
58454   RegisterTraceWriterRequest(RegisterTraceWriterRequest&&) noexcept;
58455   RegisterTraceWriterRequest& operator=(RegisterTraceWriterRequest&&);
58456   RegisterTraceWriterRequest(const RegisterTraceWriterRequest&);
58457   RegisterTraceWriterRequest& operator=(const RegisterTraceWriterRequest&);
58458   bool operator==(const RegisterTraceWriterRequest&) const;
operator !=(const RegisterTraceWriterRequest & other) const58459   bool operator!=(const RegisterTraceWriterRequest& other) const { return !(*this == other); }
58460 
58461   bool ParseFromArray(const void*, size_t) override;
58462   std::string SerializeAsString() const override;
58463   std::vector<uint8_t> SerializeAsArray() const override;
58464   void Serialize(::protozero::Message*) const;
58465 
has_trace_writer_id() const58466   bool has_trace_writer_id() const { return _has_field_[1]; }
trace_writer_id() const58467   uint32_t trace_writer_id() const { return trace_writer_id_; }
set_trace_writer_id(uint32_t value)58468   void set_trace_writer_id(uint32_t value) { trace_writer_id_ = value; _has_field_.set(1); }
58469 
has_target_buffer() const58470   bool has_target_buffer() const { return _has_field_[2]; }
target_buffer() const58471   uint32_t target_buffer() const { return target_buffer_; }
set_target_buffer(uint32_t value)58472   void set_target_buffer(uint32_t value) { target_buffer_ = value; _has_field_.set(2); }
58473 
58474  private:
58475   uint32_t trace_writer_id_{};
58476   uint32_t target_buffer_{};
58477 
58478   // Allows to preserve unknown protobuf fields for compatibility
58479   // with future versions of .proto files.
58480   std::string unknown_fields_;
58481 
58482   std::bitset<3> _has_field_{};
58483 };
58484 
58485 
58486 class PERFETTO_EXPORT UnregisterDataSourceResponse : public ::protozero::CppMessageObj {
58487  public:
58488   enum FieldNumbers {
58489   };
58490 
58491   UnregisterDataSourceResponse();
58492   ~UnregisterDataSourceResponse() override;
58493   UnregisterDataSourceResponse(UnregisterDataSourceResponse&&) noexcept;
58494   UnregisterDataSourceResponse& operator=(UnregisterDataSourceResponse&&);
58495   UnregisterDataSourceResponse(const UnregisterDataSourceResponse&);
58496   UnregisterDataSourceResponse& operator=(const UnregisterDataSourceResponse&);
58497   bool operator==(const UnregisterDataSourceResponse&) const;
operator !=(const UnregisterDataSourceResponse & other) const58498   bool operator!=(const UnregisterDataSourceResponse& other) const { return !(*this == other); }
58499 
58500   bool ParseFromArray(const void*, size_t) override;
58501   std::string SerializeAsString() const override;
58502   std::vector<uint8_t> SerializeAsArray() const override;
58503   void Serialize(::protozero::Message*) const;
58504 
58505  private:
58506 
58507   // Allows to preserve unknown protobuf fields for compatibility
58508   // with future versions of .proto files.
58509   std::string unknown_fields_;
58510 
58511   std::bitset<2> _has_field_{};
58512 };
58513 
58514 
58515 class PERFETTO_EXPORT UnregisterDataSourceRequest : public ::protozero::CppMessageObj {
58516  public:
58517   enum FieldNumbers {
58518     kDataSourceNameFieldNumber = 1,
58519   };
58520 
58521   UnregisterDataSourceRequest();
58522   ~UnregisterDataSourceRequest() override;
58523   UnregisterDataSourceRequest(UnregisterDataSourceRequest&&) noexcept;
58524   UnregisterDataSourceRequest& operator=(UnregisterDataSourceRequest&&);
58525   UnregisterDataSourceRequest(const UnregisterDataSourceRequest&);
58526   UnregisterDataSourceRequest& operator=(const UnregisterDataSourceRequest&);
58527   bool operator==(const UnregisterDataSourceRequest&) const;
operator !=(const UnregisterDataSourceRequest & other) const58528   bool operator!=(const UnregisterDataSourceRequest& other) const { return !(*this == other); }
58529 
58530   bool ParseFromArray(const void*, size_t) override;
58531   std::string SerializeAsString() const override;
58532   std::vector<uint8_t> SerializeAsArray() const override;
58533   void Serialize(::protozero::Message*) const;
58534 
has_data_source_name() const58535   bool has_data_source_name() const { return _has_field_[1]; }
data_source_name() const58536   const std::string& data_source_name() const { return data_source_name_; }
set_data_source_name(const std::string & value)58537   void set_data_source_name(const std::string& value) { data_source_name_ = value; _has_field_.set(1); }
58538 
58539  private:
58540   std::string data_source_name_{};
58541 
58542   // Allows to preserve unknown protobuf fields for compatibility
58543   // with future versions of .proto files.
58544   std::string unknown_fields_;
58545 
58546   std::bitset<2> _has_field_{};
58547 };
58548 
58549 
58550 class PERFETTO_EXPORT RegisterDataSourceResponse : public ::protozero::CppMessageObj {
58551  public:
58552   enum FieldNumbers {
58553     kErrorFieldNumber = 1,
58554   };
58555 
58556   RegisterDataSourceResponse();
58557   ~RegisterDataSourceResponse() override;
58558   RegisterDataSourceResponse(RegisterDataSourceResponse&&) noexcept;
58559   RegisterDataSourceResponse& operator=(RegisterDataSourceResponse&&);
58560   RegisterDataSourceResponse(const RegisterDataSourceResponse&);
58561   RegisterDataSourceResponse& operator=(const RegisterDataSourceResponse&);
58562   bool operator==(const RegisterDataSourceResponse&) const;
operator !=(const RegisterDataSourceResponse & other) const58563   bool operator!=(const RegisterDataSourceResponse& other) const { return !(*this == other); }
58564 
58565   bool ParseFromArray(const void*, size_t) override;
58566   std::string SerializeAsString() const override;
58567   std::vector<uint8_t> SerializeAsArray() const override;
58568   void Serialize(::protozero::Message*) const;
58569 
has_error() const58570   bool has_error() const { return _has_field_[1]; }
error() const58571   const std::string& error() const { return error_; }
set_error(const std::string & value)58572   void set_error(const std::string& value) { error_ = value; _has_field_.set(1); }
58573 
58574  private:
58575   std::string error_{};
58576 
58577   // Allows to preserve unknown protobuf fields for compatibility
58578   // with future versions of .proto files.
58579   std::string unknown_fields_;
58580 
58581   std::bitset<2> _has_field_{};
58582 };
58583 
58584 
58585 class PERFETTO_EXPORT RegisterDataSourceRequest : public ::protozero::CppMessageObj {
58586  public:
58587   enum FieldNumbers {
58588     kDataSourceDescriptorFieldNumber = 1,
58589   };
58590 
58591   RegisterDataSourceRequest();
58592   ~RegisterDataSourceRequest() override;
58593   RegisterDataSourceRequest(RegisterDataSourceRequest&&) noexcept;
58594   RegisterDataSourceRequest& operator=(RegisterDataSourceRequest&&);
58595   RegisterDataSourceRequest(const RegisterDataSourceRequest&);
58596   RegisterDataSourceRequest& operator=(const RegisterDataSourceRequest&);
58597   bool operator==(const RegisterDataSourceRequest&) const;
operator !=(const RegisterDataSourceRequest & other) const58598   bool operator!=(const RegisterDataSourceRequest& other) const { return !(*this == other); }
58599 
58600   bool ParseFromArray(const void*, size_t) override;
58601   std::string SerializeAsString() const override;
58602   std::vector<uint8_t> SerializeAsArray() const override;
58603   void Serialize(::protozero::Message*) const;
58604 
has_data_source_descriptor() const58605   bool has_data_source_descriptor() const { return _has_field_[1]; }
data_source_descriptor() const58606   const DataSourceDescriptor& data_source_descriptor() const { return *data_source_descriptor_; }
mutable_data_source_descriptor()58607   DataSourceDescriptor* mutable_data_source_descriptor() { _has_field_.set(1); return data_source_descriptor_.get(); }
58608 
58609  private:
58610   ::protozero::CopyablePtr<DataSourceDescriptor> data_source_descriptor_;
58611 
58612   // Allows to preserve unknown protobuf fields for compatibility
58613   // with future versions of .proto files.
58614   std::string unknown_fields_;
58615 
58616   std::bitset<2> _has_field_{};
58617 };
58618 
58619 
58620 class PERFETTO_EXPORT InitializeConnectionResponse : public ::protozero::CppMessageObj {
58621  public:
58622   enum FieldNumbers {
58623     kUsingShmemProvidedByProducerFieldNumber = 1,
58624     kDirectSmbPatchingSupportedFieldNumber = 2,
58625   };
58626 
58627   InitializeConnectionResponse();
58628   ~InitializeConnectionResponse() override;
58629   InitializeConnectionResponse(InitializeConnectionResponse&&) noexcept;
58630   InitializeConnectionResponse& operator=(InitializeConnectionResponse&&);
58631   InitializeConnectionResponse(const InitializeConnectionResponse&);
58632   InitializeConnectionResponse& operator=(const InitializeConnectionResponse&);
58633   bool operator==(const InitializeConnectionResponse&) const;
operator !=(const InitializeConnectionResponse & other) const58634   bool operator!=(const InitializeConnectionResponse& other) const { return !(*this == other); }
58635 
58636   bool ParseFromArray(const void*, size_t) override;
58637   std::string SerializeAsString() const override;
58638   std::vector<uint8_t> SerializeAsArray() const override;
58639   void Serialize(::protozero::Message*) const;
58640 
has_using_shmem_provided_by_producer() const58641   bool has_using_shmem_provided_by_producer() const { return _has_field_[1]; }
using_shmem_provided_by_producer() const58642   bool using_shmem_provided_by_producer() const { return using_shmem_provided_by_producer_; }
set_using_shmem_provided_by_producer(bool value)58643   void set_using_shmem_provided_by_producer(bool value) { using_shmem_provided_by_producer_ = value; _has_field_.set(1); }
58644 
has_direct_smb_patching_supported() const58645   bool has_direct_smb_patching_supported() const { return _has_field_[2]; }
direct_smb_patching_supported() const58646   bool direct_smb_patching_supported() const { return direct_smb_patching_supported_; }
set_direct_smb_patching_supported(bool value)58647   void set_direct_smb_patching_supported(bool value) { direct_smb_patching_supported_ = value; _has_field_.set(2); }
58648 
58649  private:
58650   bool using_shmem_provided_by_producer_{};
58651   bool direct_smb_patching_supported_{};
58652 
58653   // Allows to preserve unknown protobuf fields for compatibility
58654   // with future versions of .proto files.
58655   std::string unknown_fields_;
58656 
58657   std::bitset<3> _has_field_{};
58658 };
58659 
58660 
58661 class PERFETTO_EXPORT InitializeConnectionRequest : public ::protozero::CppMessageObj {
58662  public:
58663   using ProducerSMBScrapingMode = InitializeConnectionRequest_ProducerSMBScrapingMode;
58664   static constexpr auto SMB_SCRAPING_UNSPECIFIED = InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_UNSPECIFIED;
58665   static constexpr auto SMB_SCRAPING_ENABLED = InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_ENABLED;
58666   static constexpr auto SMB_SCRAPING_DISABLED = InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_DISABLED;
58667   static constexpr auto ProducerSMBScrapingMode_MIN = InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_UNSPECIFIED;
58668   static constexpr auto ProducerSMBScrapingMode_MAX = InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_DISABLED;
58669   using ProducerBuildFlags = InitializeConnectionRequest_ProducerBuildFlags;
58670   static constexpr auto BUILD_FLAGS_UNSPECIFIED = InitializeConnectionRequest_ProducerBuildFlags_BUILD_FLAGS_UNSPECIFIED;
58671   static constexpr auto BUILD_FLAGS_DCHECKS_ON = InitializeConnectionRequest_ProducerBuildFlags_BUILD_FLAGS_DCHECKS_ON;
58672   static constexpr auto BUILD_FLAGS_DCHECKS_OFF = InitializeConnectionRequest_ProducerBuildFlags_BUILD_FLAGS_DCHECKS_OFF;
58673   static constexpr auto ProducerBuildFlags_MIN = InitializeConnectionRequest_ProducerBuildFlags_BUILD_FLAGS_UNSPECIFIED;
58674   static constexpr auto ProducerBuildFlags_MAX = InitializeConnectionRequest_ProducerBuildFlags_BUILD_FLAGS_DCHECKS_OFF;
58675   enum FieldNumbers {
58676     kSharedMemoryPageSizeHintBytesFieldNumber = 1,
58677     kSharedMemorySizeHintBytesFieldNumber = 2,
58678     kProducerNameFieldNumber = 3,
58679     kSmbScrapingModeFieldNumber = 4,
58680     kBuildFlagsFieldNumber = 5,
58681     kProducerProvidedShmemFieldNumber = 6,
58682     kSdkVersionFieldNumber = 8,
58683   };
58684 
58685   InitializeConnectionRequest();
58686   ~InitializeConnectionRequest() override;
58687   InitializeConnectionRequest(InitializeConnectionRequest&&) noexcept;
58688   InitializeConnectionRequest& operator=(InitializeConnectionRequest&&);
58689   InitializeConnectionRequest(const InitializeConnectionRequest&);
58690   InitializeConnectionRequest& operator=(const InitializeConnectionRequest&);
58691   bool operator==(const InitializeConnectionRequest&) const;
operator !=(const InitializeConnectionRequest & other) const58692   bool operator!=(const InitializeConnectionRequest& other) const { return !(*this == other); }
58693 
58694   bool ParseFromArray(const void*, size_t) override;
58695   std::string SerializeAsString() const override;
58696   std::vector<uint8_t> SerializeAsArray() const override;
58697   void Serialize(::protozero::Message*) const;
58698 
has_shared_memory_page_size_hint_bytes() const58699   bool has_shared_memory_page_size_hint_bytes() const { return _has_field_[1]; }
shared_memory_page_size_hint_bytes() const58700   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)58701   void set_shared_memory_page_size_hint_bytes(uint32_t value) { shared_memory_page_size_hint_bytes_ = value; _has_field_.set(1); }
58702 
has_shared_memory_size_hint_bytes() const58703   bool has_shared_memory_size_hint_bytes() const { return _has_field_[2]; }
shared_memory_size_hint_bytes() const58704   uint32_t shared_memory_size_hint_bytes() const { return shared_memory_size_hint_bytes_; }
set_shared_memory_size_hint_bytes(uint32_t value)58705   void set_shared_memory_size_hint_bytes(uint32_t value) { shared_memory_size_hint_bytes_ = value; _has_field_.set(2); }
58706 
has_producer_name() const58707   bool has_producer_name() const { return _has_field_[3]; }
producer_name() const58708   const std::string& producer_name() const { return producer_name_; }
set_producer_name(const std::string & value)58709   void set_producer_name(const std::string& value) { producer_name_ = value; _has_field_.set(3); }
58710 
has_smb_scraping_mode() const58711   bool has_smb_scraping_mode() const { return _has_field_[4]; }
smb_scraping_mode() const58712   InitializeConnectionRequest_ProducerSMBScrapingMode smb_scraping_mode() const { return smb_scraping_mode_; }
set_smb_scraping_mode(InitializeConnectionRequest_ProducerSMBScrapingMode value)58713   void set_smb_scraping_mode(InitializeConnectionRequest_ProducerSMBScrapingMode value) { smb_scraping_mode_ = value; _has_field_.set(4); }
58714 
has_build_flags() const58715   bool has_build_flags() const { return _has_field_[5]; }
build_flags() const58716   InitializeConnectionRequest_ProducerBuildFlags build_flags() const { return build_flags_; }
set_build_flags(InitializeConnectionRequest_ProducerBuildFlags value)58717   void set_build_flags(InitializeConnectionRequest_ProducerBuildFlags value) { build_flags_ = value; _has_field_.set(5); }
58718 
has_producer_provided_shmem() const58719   bool has_producer_provided_shmem() const { return _has_field_[6]; }
producer_provided_shmem() const58720   bool producer_provided_shmem() const { return producer_provided_shmem_; }
set_producer_provided_shmem(bool value)58721   void set_producer_provided_shmem(bool value) { producer_provided_shmem_ = value; _has_field_.set(6); }
58722 
has_sdk_version() const58723   bool has_sdk_version() const { return _has_field_[8]; }
sdk_version() const58724   const std::string& sdk_version() const { return sdk_version_; }
set_sdk_version(const std::string & value)58725   void set_sdk_version(const std::string& value) { sdk_version_ = value; _has_field_.set(8); }
58726 
58727  private:
58728   uint32_t shared_memory_page_size_hint_bytes_{};
58729   uint32_t shared_memory_size_hint_bytes_{};
58730   std::string producer_name_{};
58731   InitializeConnectionRequest_ProducerSMBScrapingMode smb_scraping_mode_{};
58732   InitializeConnectionRequest_ProducerBuildFlags build_flags_{};
58733   bool producer_provided_shmem_{};
58734   std::string sdk_version_{};
58735 
58736   // Allows to preserve unknown protobuf fields for compatibility
58737   // with future versions of .proto files.
58738   std::string unknown_fields_;
58739 
58740   std::bitset<9> _has_field_{};
58741 };
58742 
58743 }  // namespace perfetto
58744 }  // namespace protos
58745 }  // namespace gen
58746 
58747 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_PRODUCER_PORT_PROTO_CPP_H_
58748 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
58749 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
58750 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
58751 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
58752 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
58753 #if defined(__GNUC__) || defined(__clang__)
58754 #pragma GCC diagnostic push
58755 #pragma GCC diagnostic ignored "-Wfloat-equal"
58756 #endif
58757 // gen_amalgamated expanded: #include "protos/perfetto/ipc/producer_port.gen.h"
58758 // gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
58759 // gen_amalgamated expanded: #include "protos/perfetto/common/track_event_descriptor.gen.h"
58760 // gen_amalgamated expanded: #include "protos/perfetto/common/gpu_counter_descriptor.gen.h"
58761 // gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
58762 // gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"
58763 // gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
58764 // gen_amalgamated expanded: #include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
58765 // gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
58766 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/perf_event_config.gen.h"
58767 // gen_amalgamated expanded: #include "protos/perfetto/common/perf_events.gen.h"
58768 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/java_hprof_config.gen.h"
58769 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/heapprofd_config.gen.h"
58770 // gen_amalgamated expanded: #include "protos/perfetto/config/process_stats/process_stats_config.gen.h"
58771 // gen_amalgamated expanded: #include "protos/perfetto/config/power/android_power_config.gen.h"
58772 // gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
58773 // gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
58774 // gen_amalgamated expanded: #include "protos/perfetto/config/inode_file/inode_file_config.gen.h"
58775 // gen_amalgamated expanded: #include "protos/perfetto/config/gpu/vulkan_memory_config.gen.h"
58776 // gen_amalgamated expanded: #include "protos/perfetto/config/gpu/gpu_counter_config.gen.h"
58777 // gen_amalgamated expanded: #include "protos/perfetto/config/ftrace/ftrace_config.gen.h"
58778 // gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
58779 // gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_config.gen.h"
58780 // gen_amalgamated expanded: #include "protos/perfetto/config/android/android_polled_state_config.gen.h"
58781 // gen_amalgamated expanded: #include "protos/perfetto/config/android/android_log_config.gen.h"
58782 // gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
58783 // gen_amalgamated expanded: #include "protos/perfetto/common/commit_data_request.gen.h"
58784 
58785 namespace perfetto {
58786 namespace protos {
58787 namespace gen {
58788 
58789 SyncResponse::SyncResponse() = default;
58790 SyncResponse::~SyncResponse() = default;
58791 SyncResponse::SyncResponse(const SyncResponse&) = default;
58792 SyncResponse& SyncResponse::operator=(const SyncResponse&) = default;
58793 SyncResponse::SyncResponse(SyncResponse&&) noexcept = default;
58794 SyncResponse& SyncResponse::operator=(SyncResponse&&) = default;
58795 
operator ==(const SyncResponse & other) const58796 bool SyncResponse::operator==(const SyncResponse& other) const {
58797   return unknown_fields_ == other.unknown_fields_;
58798 }
58799 
ParseFromArray(const void * raw,size_t size)58800 bool SyncResponse::ParseFromArray(const void* raw, size_t size) {
58801   unknown_fields_.clear();
58802   bool packed_error = false;
58803 
58804   ::protozero::ProtoDecoder dec(raw, size);
58805   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
58806     if (field.id() < _has_field_.size()) {
58807       _has_field_.set(field.id());
58808     }
58809     switch (field.id()) {
58810       default:
58811         field.SerializeAndAppendTo(&unknown_fields_);
58812         break;
58813     }
58814   }
58815   return !packed_error && !dec.bytes_left();
58816 }
58817 
SerializeAsString() const58818 std::string SyncResponse::SerializeAsString() const {
58819   ::protozero::HeapBuffered<::protozero::Message> msg;
58820   Serialize(msg.get());
58821   return msg.SerializeAsString();
58822 }
58823 
SerializeAsArray() const58824 std::vector<uint8_t> SyncResponse::SerializeAsArray() const {
58825   ::protozero::HeapBuffered<::protozero::Message> msg;
58826   Serialize(msg.get());
58827   return msg.SerializeAsArray();
58828 }
58829 
Serialize(::protozero::Message * msg) const58830 void SyncResponse::Serialize(::protozero::Message* msg) const {
58831   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
58832 }
58833 
58834 
58835 SyncRequest::SyncRequest() = default;
58836 SyncRequest::~SyncRequest() = default;
58837 SyncRequest::SyncRequest(const SyncRequest&) = default;
58838 SyncRequest& SyncRequest::operator=(const SyncRequest&) = default;
58839 SyncRequest::SyncRequest(SyncRequest&&) noexcept = default;
58840 SyncRequest& SyncRequest::operator=(SyncRequest&&) = default;
58841 
operator ==(const SyncRequest & other) const58842 bool SyncRequest::operator==(const SyncRequest& other) const {
58843   return unknown_fields_ == other.unknown_fields_;
58844 }
58845 
ParseFromArray(const void * raw,size_t size)58846 bool SyncRequest::ParseFromArray(const void* raw, size_t size) {
58847   unknown_fields_.clear();
58848   bool packed_error = false;
58849 
58850   ::protozero::ProtoDecoder dec(raw, size);
58851   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
58852     if (field.id() < _has_field_.size()) {
58853       _has_field_.set(field.id());
58854     }
58855     switch (field.id()) {
58856       default:
58857         field.SerializeAndAppendTo(&unknown_fields_);
58858         break;
58859     }
58860   }
58861   return !packed_error && !dec.bytes_left();
58862 }
58863 
SerializeAsString() const58864 std::string SyncRequest::SerializeAsString() const {
58865   ::protozero::HeapBuffered<::protozero::Message> msg;
58866   Serialize(msg.get());
58867   return msg.SerializeAsString();
58868 }
58869 
SerializeAsArray() const58870 std::vector<uint8_t> SyncRequest::SerializeAsArray() const {
58871   ::protozero::HeapBuffered<::protozero::Message> msg;
58872   Serialize(msg.get());
58873   return msg.SerializeAsArray();
58874 }
58875 
Serialize(::protozero::Message * msg) const58876 void SyncRequest::Serialize(::protozero::Message* msg) const {
58877   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
58878 }
58879 
58880 
58881 GetAsyncCommandResponse::GetAsyncCommandResponse() = default;
58882 GetAsyncCommandResponse::~GetAsyncCommandResponse() = default;
58883 GetAsyncCommandResponse::GetAsyncCommandResponse(const GetAsyncCommandResponse&) = default;
58884 GetAsyncCommandResponse& GetAsyncCommandResponse::operator=(const GetAsyncCommandResponse&) = default;
58885 GetAsyncCommandResponse::GetAsyncCommandResponse(GetAsyncCommandResponse&&) noexcept = default;
58886 GetAsyncCommandResponse& GetAsyncCommandResponse::operator=(GetAsyncCommandResponse&&) = default;
58887 
operator ==(const GetAsyncCommandResponse & other) const58888 bool GetAsyncCommandResponse::operator==(const GetAsyncCommandResponse& other) const {
58889   return unknown_fields_ == other.unknown_fields_
58890    && setup_tracing_ == other.setup_tracing_
58891    && setup_data_source_ == other.setup_data_source_
58892    && start_data_source_ == other.start_data_source_
58893    && stop_data_source_ == other.stop_data_source_
58894    && flush_ == other.flush_
58895    && clear_incremental_state_ == other.clear_incremental_state_;
58896 }
58897 
ParseFromArray(const void * raw,size_t size)58898 bool GetAsyncCommandResponse::ParseFromArray(const void* raw, size_t size) {
58899   unknown_fields_.clear();
58900   bool packed_error = false;
58901 
58902   ::protozero::ProtoDecoder dec(raw, size);
58903   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
58904     if (field.id() < _has_field_.size()) {
58905       _has_field_.set(field.id());
58906     }
58907     switch (field.id()) {
58908       case 3 /* setup_tracing */:
58909         (*setup_tracing_).ParseFromArray(field.data(), field.size());
58910         break;
58911       case 6 /* setup_data_source */:
58912         (*setup_data_source_).ParseFromArray(field.data(), field.size());
58913         break;
58914       case 1 /* start_data_source */:
58915         (*start_data_source_).ParseFromArray(field.data(), field.size());
58916         break;
58917       case 2 /* stop_data_source */:
58918         (*stop_data_source_).ParseFromArray(field.data(), field.size());
58919         break;
58920       case 5 /* flush */:
58921         (*flush_).ParseFromArray(field.data(), field.size());
58922         break;
58923       case 7 /* clear_incremental_state */:
58924         (*clear_incremental_state_).ParseFromArray(field.data(), field.size());
58925         break;
58926       default:
58927         field.SerializeAndAppendTo(&unknown_fields_);
58928         break;
58929     }
58930   }
58931   return !packed_error && !dec.bytes_left();
58932 }
58933 
SerializeAsString() const58934 std::string GetAsyncCommandResponse::SerializeAsString() const {
58935   ::protozero::HeapBuffered<::protozero::Message> msg;
58936   Serialize(msg.get());
58937   return msg.SerializeAsString();
58938 }
58939 
SerializeAsArray() const58940 std::vector<uint8_t> GetAsyncCommandResponse::SerializeAsArray() const {
58941   ::protozero::HeapBuffered<::protozero::Message> msg;
58942   Serialize(msg.get());
58943   return msg.SerializeAsArray();
58944 }
58945 
Serialize(::protozero::Message * msg) const58946 void GetAsyncCommandResponse::Serialize(::protozero::Message* msg) const {
58947   // Field 3: setup_tracing
58948   if (_has_field_[3]) {
58949     (*setup_tracing_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
58950   }
58951 
58952   // Field 6: setup_data_source
58953   if (_has_field_[6]) {
58954     (*setup_data_source_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
58955   }
58956 
58957   // Field 1: start_data_source
58958   if (_has_field_[1]) {
58959     (*start_data_source_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
58960   }
58961 
58962   // Field 2: stop_data_source
58963   if (_has_field_[2]) {
58964     (*stop_data_source_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
58965   }
58966 
58967   // Field 5: flush
58968   if (_has_field_[5]) {
58969     (*flush_).Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
58970   }
58971 
58972   // Field 7: clear_incremental_state
58973   if (_has_field_[7]) {
58974     (*clear_incremental_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
58975   }
58976 
58977   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
58978 }
58979 
58980 
58981 GetAsyncCommandResponse_ClearIncrementalState::GetAsyncCommandResponse_ClearIncrementalState() = default;
58982 GetAsyncCommandResponse_ClearIncrementalState::~GetAsyncCommandResponse_ClearIncrementalState() = default;
58983 GetAsyncCommandResponse_ClearIncrementalState::GetAsyncCommandResponse_ClearIncrementalState(const GetAsyncCommandResponse_ClearIncrementalState&) = default;
58984 GetAsyncCommandResponse_ClearIncrementalState& GetAsyncCommandResponse_ClearIncrementalState::operator=(const GetAsyncCommandResponse_ClearIncrementalState&) = default;
58985 GetAsyncCommandResponse_ClearIncrementalState::GetAsyncCommandResponse_ClearIncrementalState(GetAsyncCommandResponse_ClearIncrementalState&&) noexcept = default;
58986 GetAsyncCommandResponse_ClearIncrementalState& GetAsyncCommandResponse_ClearIncrementalState::operator=(GetAsyncCommandResponse_ClearIncrementalState&&) = default;
58987 
operator ==(const GetAsyncCommandResponse_ClearIncrementalState & other) const58988 bool GetAsyncCommandResponse_ClearIncrementalState::operator==(const GetAsyncCommandResponse_ClearIncrementalState& other) const {
58989   return unknown_fields_ == other.unknown_fields_
58990    && data_source_ids_ == other.data_source_ids_;
58991 }
58992 
ParseFromArray(const void * raw,size_t size)58993 bool GetAsyncCommandResponse_ClearIncrementalState::ParseFromArray(const void* raw, size_t size) {
58994   data_source_ids_.clear();
58995   unknown_fields_.clear();
58996   bool packed_error = false;
58997 
58998   ::protozero::ProtoDecoder dec(raw, size);
58999   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
59000     if (field.id() < _has_field_.size()) {
59001       _has_field_.set(field.id());
59002     }
59003     switch (field.id()) {
59004       case 1 /* data_source_ids */:
59005         data_source_ids_.emplace_back();
59006         field.get(&data_source_ids_.back());
59007         break;
59008       default:
59009         field.SerializeAndAppendTo(&unknown_fields_);
59010         break;
59011     }
59012   }
59013   return !packed_error && !dec.bytes_left();
59014 }
59015 
SerializeAsString() const59016 std::string GetAsyncCommandResponse_ClearIncrementalState::SerializeAsString() const {
59017   ::protozero::HeapBuffered<::protozero::Message> msg;
59018   Serialize(msg.get());
59019   return msg.SerializeAsString();
59020 }
59021 
SerializeAsArray() const59022 std::vector<uint8_t> GetAsyncCommandResponse_ClearIncrementalState::SerializeAsArray() const {
59023   ::protozero::HeapBuffered<::protozero::Message> msg;
59024   Serialize(msg.get());
59025   return msg.SerializeAsArray();
59026 }
59027 
Serialize(::protozero::Message * msg) const59028 void GetAsyncCommandResponse_ClearIncrementalState::Serialize(::protozero::Message* msg) const {
59029   // Field 1: data_source_ids
59030   for (auto& it : data_source_ids_) {
59031     msg->AppendVarInt(1, it);
59032   }
59033 
59034   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59035 }
59036 
59037 
59038 GetAsyncCommandResponse_Flush::GetAsyncCommandResponse_Flush() = default;
59039 GetAsyncCommandResponse_Flush::~GetAsyncCommandResponse_Flush() = default;
59040 GetAsyncCommandResponse_Flush::GetAsyncCommandResponse_Flush(const GetAsyncCommandResponse_Flush&) = default;
59041 GetAsyncCommandResponse_Flush& GetAsyncCommandResponse_Flush::operator=(const GetAsyncCommandResponse_Flush&) = default;
59042 GetAsyncCommandResponse_Flush::GetAsyncCommandResponse_Flush(GetAsyncCommandResponse_Flush&&) noexcept = default;
59043 GetAsyncCommandResponse_Flush& GetAsyncCommandResponse_Flush::operator=(GetAsyncCommandResponse_Flush&&) = default;
59044 
operator ==(const GetAsyncCommandResponse_Flush & other) const59045 bool GetAsyncCommandResponse_Flush::operator==(const GetAsyncCommandResponse_Flush& other) const {
59046   return unknown_fields_ == other.unknown_fields_
59047    && data_source_ids_ == other.data_source_ids_
59048    && request_id_ == other.request_id_;
59049 }
59050 
ParseFromArray(const void * raw,size_t size)59051 bool GetAsyncCommandResponse_Flush::ParseFromArray(const void* raw, size_t size) {
59052   data_source_ids_.clear();
59053   unknown_fields_.clear();
59054   bool packed_error = false;
59055 
59056   ::protozero::ProtoDecoder dec(raw, size);
59057   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
59058     if (field.id() < _has_field_.size()) {
59059       _has_field_.set(field.id());
59060     }
59061     switch (field.id()) {
59062       case 1 /* data_source_ids */:
59063         data_source_ids_.emplace_back();
59064         field.get(&data_source_ids_.back());
59065         break;
59066       case 2 /* request_id */:
59067         field.get(&request_id_);
59068         break;
59069       default:
59070         field.SerializeAndAppendTo(&unknown_fields_);
59071         break;
59072     }
59073   }
59074   return !packed_error && !dec.bytes_left();
59075 }
59076 
SerializeAsString() const59077 std::string GetAsyncCommandResponse_Flush::SerializeAsString() const {
59078   ::protozero::HeapBuffered<::protozero::Message> msg;
59079   Serialize(msg.get());
59080   return msg.SerializeAsString();
59081 }
59082 
SerializeAsArray() const59083 std::vector<uint8_t> GetAsyncCommandResponse_Flush::SerializeAsArray() const {
59084   ::protozero::HeapBuffered<::protozero::Message> msg;
59085   Serialize(msg.get());
59086   return msg.SerializeAsArray();
59087 }
59088 
Serialize(::protozero::Message * msg) const59089 void GetAsyncCommandResponse_Flush::Serialize(::protozero::Message* msg) const {
59090   // Field 1: data_source_ids
59091   for (auto& it : data_source_ids_) {
59092     msg->AppendVarInt(1, it);
59093   }
59094 
59095   // Field 2: request_id
59096   if (_has_field_[2]) {
59097     msg->AppendVarInt(2, request_id_);
59098   }
59099 
59100   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59101 }
59102 
59103 
59104 GetAsyncCommandResponse_StopDataSource::GetAsyncCommandResponse_StopDataSource() = default;
59105 GetAsyncCommandResponse_StopDataSource::~GetAsyncCommandResponse_StopDataSource() = default;
59106 GetAsyncCommandResponse_StopDataSource::GetAsyncCommandResponse_StopDataSource(const GetAsyncCommandResponse_StopDataSource&) = default;
59107 GetAsyncCommandResponse_StopDataSource& GetAsyncCommandResponse_StopDataSource::operator=(const GetAsyncCommandResponse_StopDataSource&) = default;
59108 GetAsyncCommandResponse_StopDataSource::GetAsyncCommandResponse_StopDataSource(GetAsyncCommandResponse_StopDataSource&&) noexcept = default;
59109 GetAsyncCommandResponse_StopDataSource& GetAsyncCommandResponse_StopDataSource::operator=(GetAsyncCommandResponse_StopDataSource&&) = default;
59110 
operator ==(const GetAsyncCommandResponse_StopDataSource & other) const59111 bool GetAsyncCommandResponse_StopDataSource::operator==(const GetAsyncCommandResponse_StopDataSource& other) const {
59112   return unknown_fields_ == other.unknown_fields_
59113    && instance_id_ == other.instance_id_;
59114 }
59115 
ParseFromArray(const void * raw,size_t size)59116 bool GetAsyncCommandResponse_StopDataSource::ParseFromArray(const void* raw, size_t size) {
59117   unknown_fields_.clear();
59118   bool packed_error = false;
59119 
59120   ::protozero::ProtoDecoder dec(raw, size);
59121   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
59122     if (field.id() < _has_field_.size()) {
59123       _has_field_.set(field.id());
59124     }
59125     switch (field.id()) {
59126       case 1 /* instance_id */:
59127         field.get(&instance_id_);
59128         break;
59129       default:
59130         field.SerializeAndAppendTo(&unknown_fields_);
59131         break;
59132     }
59133   }
59134   return !packed_error && !dec.bytes_left();
59135 }
59136 
SerializeAsString() const59137 std::string GetAsyncCommandResponse_StopDataSource::SerializeAsString() const {
59138   ::protozero::HeapBuffered<::protozero::Message> msg;
59139   Serialize(msg.get());
59140   return msg.SerializeAsString();
59141 }
59142 
SerializeAsArray() const59143 std::vector<uint8_t> GetAsyncCommandResponse_StopDataSource::SerializeAsArray() const {
59144   ::protozero::HeapBuffered<::protozero::Message> msg;
59145   Serialize(msg.get());
59146   return msg.SerializeAsArray();
59147 }
59148 
Serialize(::protozero::Message * msg) const59149 void GetAsyncCommandResponse_StopDataSource::Serialize(::protozero::Message* msg) const {
59150   // Field 1: instance_id
59151   if (_has_field_[1]) {
59152     msg->AppendVarInt(1, instance_id_);
59153   }
59154 
59155   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59156 }
59157 
59158 
59159 GetAsyncCommandResponse_StartDataSource::GetAsyncCommandResponse_StartDataSource() = default;
59160 GetAsyncCommandResponse_StartDataSource::~GetAsyncCommandResponse_StartDataSource() = default;
59161 GetAsyncCommandResponse_StartDataSource::GetAsyncCommandResponse_StartDataSource(const GetAsyncCommandResponse_StartDataSource&) = default;
59162 GetAsyncCommandResponse_StartDataSource& GetAsyncCommandResponse_StartDataSource::operator=(const GetAsyncCommandResponse_StartDataSource&) = default;
59163 GetAsyncCommandResponse_StartDataSource::GetAsyncCommandResponse_StartDataSource(GetAsyncCommandResponse_StartDataSource&&) noexcept = default;
59164 GetAsyncCommandResponse_StartDataSource& GetAsyncCommandResponse_StartDataSource::operator=(GetAsyncCommandResponse_StartDataSource&&) = default;
59165 
operator ==(const GetAsyncCommandResponse_StartDataSource & other) const59166 bool GetAsyncCommandResponse_StartDataSource::operator==(const GetAsyncCommandResponse_StartDataSource& other) const {
59167   return unknown_fields_ == other.unknown_fields_
59168    && new_instance_id_ == other.new_instance_id_
59169    && config_ == other.config_;
59170 }
59171 
ParseFromArray(const void * raw,size_t size)59172 bool GetAsyncCommandResponse_StartDataSource::ParseFromArray(const void* raw, size_t size) {
59173   unknown_fields_.clear();
59174   bool packed_error = false;
59175 
59176   ::protozero::ProtoDecoder dec(raw, size);
59177   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
59178     if (field.id() < _has_field_.size()) {
59179       _has_field_.set(field.id());
59180     }
59181     switch (field.id()) {
59182       case 1 /* new_instance_id */:
59183         field.get(&new_instance_id_);
59184         break;
59185       case 2 /* config */:
59186         (*config_).ParseFromArray(field.data(), field.size());
59187         break;
59188       default:
59189         field.SerializeAndAppendTo(&unknown_fields_);
59190         break;
59191     }
59192   }
59193   return !packed_error && !dec.bytes_left();
59194 }
59195 
SerializeAsString() const59196 std::string GetAsyncCommandResponse_StartDataSource::SerializeAsString() const {
59197   ::protozero::HeapBuffered<::protozero::Message> msg;
59198   Serialize(msg.get());
59199   return msg.SerializeAsString();
59200 }
59201 
SerializeAsArray() const59202 std::vector<uint8_t> GetAsyncCommandResponse_StartDataSource::SerializeAsArray() const {
59203   ::protozero::HeapBuffered<::protozero::Message> msg;
59204   Serialize(msg.get());
59205   return msg.SerializeAsArray();
59206 }
59207 
Serialize(::protozero::Message * msg) const59208 void GetAsyncCommandResponse_StartDataSource::Serialize(::protozero::Message* msg) const {
59209   // Field 1: new_instance_id
59210   if (_has_field_[1]) {
59211     msg->AppendVarInt(1, new_instance_id_);
59212   }
59213 
59214   // Field 2: config
59215   if (_has_field_[2]) {
59216     (*config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
59217   }
59218 
59219   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59220 }
59221 
59222 
59223 GetAsyncCommandResponse_SetupDataSource::GetAsyncCommandResponse_SetupDataSource() = default;
59224 GetAsyncCommandResponse_SetupDataSource::~GetAsyncCommandResponse_SetupDataSource() = default;
59225 GetAsyncCommandResponse_SetupDataSource::GetAsyncCommandResponse_SetupDataSource(const GetAsyncCommandResponse_SetupDataSource&) = default;
59226 GetAsyncCommandResponse_SetupDataSource& GetAsyncCommandResponse_SetupDataSource::operator=(const GetAsyncCommandResponse_SetupDataSource&) = default;
59227 GetAsyncCommandResponse_SetupDataSource::GetAsyncCommandResponse_SetupDataSource(GetAsyncCommandResponse_SetupDataSource&&) noexcept = default;
59228 GetAsyncCommandResponse_SetupDataSource& GetAsyncCommandResponse_SetupDataSource::operator=(GetAsyncCommandResponse_SetupDataSource&&) = default;
59229 
operator ==(const GetAsyncCommandResponse_SetupDataSource & other) const59230 bool GetAsyncCommandResponse_SetupDataSource::operator==(const GetAsyncCommandResponse_SetupDataSource& other) const {
59231   return unknown_fields_ == other.unknown_fields_
59232    && new_instance_id_ == other.new_instance_id_
59233    && config_ == other.config_;
59234 }
59235 
ParseFromArray(const void * raw,size_t size)59236 bool GetAsyncCommandResponse_SetupDataSource::ParseFromArray(const void* raw, size_t size) {
59237   unknown_fields_.clear();
59238   bool packed_error = false;
59239 
59240   ::protozero::ProtoDecoder dec(raw, size);
59241   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
59242     if (field.id() < _has_field_.size()) {
59243       _has_field_.set(field.id());
59244     }
59245     switch (field.id()) {
59246       case 1 /* new_instance_id */:
59247         field.get(&new_instance_id_);
59248         break;
59249       case 2 /* config */:
59250         (*config_).ParseFromArray(field.data(), field.size());
59251         break;
59252       default:
59253         field.SerializeAndAppendTo(&unknown_fields_);
59254         break;
59255     }
59256   }
59257   return !packed_error && !dec.bytes_left();
59258 }
59259 
SerializeAsString() const59260 std::string GetAsyncCommandResponse_SetupDataSource::SerializeAsString() const {
59261   ::protozero::HeapBuffered<::protozero::Message> msg;
59262   Serialize(msg.get());
59263   return msg.SerializeAsString();
59264 }
59265 
SerializeAsArray() const59266 std::vector<uint8_t> GetAsyncCommandResponse_SetupDataSource::SerializeAsArray() const {
59267   ::protozero::HeapBuffered<::protozero::Message> msg;
59268   Serialize(msg.get());
59269   return msg.SerializeAsArray();
59270 }
59271 
Serialize(::protozero::Message * msg) const59272 void GetAsyncCommandResponse_SetupDataSource::Serialize(::protozero::Message* msg) const {
59273   // Field 1: new_instance_id
59274   if (_has_field_[1]) {
59275     msg->AppendVarInt(1, new_instance_id_);
59276   }
59277 
59278   // Field 2: config
59279   if (_has_field_[2]) {
59280     (*config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
59281   }
59282 
59283   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59284 }
59285 
59286 
59287 GetAsyncCommandResponse_SetupTracing::GetAsyncCommandResponse_SetupTracing() = default;
59288 GetAsyncCommandResponse_SetupTracing::~GetAsyncCommandResponse_SetupTracing() = default;
59289 GetAsyncCommandResponse_SetupTracing::GetAsyncCommandResponse_SetupTracing(const GetAsyncCommandResponse_SetupTracing&) = default;
59290 GetAsyncCommandResponse_SetupTracing& GetAsyncCommandResponse_SetupTracing::operator=(const GetAsyncCommandResponse_SetupTracing&) = default;
59291 GetAsyncCommandResponse_SetupTracing::GetAsyncCommandResponse_SetupTracing(GetAsyncCommandResponse_SetupTracing&&) noexcept = default;
59292 GetAsyncCommandResponse_SetupTracing& GetAsyncCommandResponse_SetupTracing::operator=(GetAsyncCommandResponse_SetupTracing&&) = default;
59293 
operator ==(const GetAsyncCommandResponse_SetupTracing & other) const59294 bool GetAsyncCommandResponse_SetupTracing::operator==(const GetAsyncCommandResponse_SetupTracing& other) const {
59295   return unknown_fields_ == other.unknown_fields_
59296    && shared_buffer_page_size_kb_ == other.shared_buffer_page_size_kb_;
59297 }
59298 
ParseFromArray(const void * raw,size_t size)59299 bool GetAsyncCommandResponse_SetupTracing::ParseFromArray(const void* raw, size_t size) {
59300   unknown_fields_.clear();
59301   bool packed_error = false;
59302 
59303   ::protozero::ProtoDecoder dec(raw, size);
59304   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
59305     if (field.id() < _has_field_.size()) {
59306       _has_field_.set(field.id());
59307     }
59308     switch (field.id()) {
59309       case 1 /* shared_buffer_page_size_kb */:
59310         field.get(&shared_buffer_page_size_kb_);
59311         break;
59312       default:
59313         field.SerializeAndAppendTo(&unknown_fields_);
59314         break;
59315     }
59316   }
59317   return !packed_error && !dec.bytes_left();
59318 }
59319 
SerializeAsString() const59320 std::string GetAsyncCommandResponse_SetupTracing::SerializeAsString() const {
59321   ::protozero::HeapBuffered<::protozero::Message> msg;
59322   Serialize(msg.get());
59323   return msg.SerializeAsString();
59324 }
59325 
SerializeAsArray() const59326 std::vector<uint8_t> GetAsyncCommandResponse_SetupTracing::SerializeAsArray() const {
59327   ::protozero::HeapBuffered<::protozero::Message> msg;
59328   Serialize(msg.get());
59329   return msg.SerializeAsArray();
59330 }
59331 
Serialize(::protozero::Message * msg) const59332 void GetAsyncCommandResponse_SetupTracing::Serialize(::protozero::Message* msg) const {
59333   // Field 1: shared_buffer_page_size_kb
59334   if (_has_field_[1]) {
59335     msg->AppendVarInt(1, shared_buffer_page_size_kb_);
59336   }
59337 
59338   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59339 }
59340 
59341 
59342 GetAsyncCommandRequest::GetAsyncCommandRequest() = default;
59343 GetAsyncCommandRequest::~GetAsyncCommandRequest() = default;
59344 GetAsyncCommandRequest::GetAsyncCommandRequest(const GetAsyncCommandRequest&) = default;
59345 GetAsyncCommandRequest& GetAsyncCommandRequest::operator=(const GetAsyncCommandRequest&) = default;
59346 GetAsyncCommandRequest::GetAsyncCommandRequest(GetAsyncCommandRequest&&) noexcept = default;
59347 GetAsyncCommandRequest& GetAsyncCommandRequest::operator=(GetAsyncCommandRequest&&) = default;
59348 
operator ==(const GetAsyncCommandRequest & other) const59349 bool GetAsyncCommandRequest::operator==(const GetAsyncCommandRequest& other) const {
59350   return unknown_fields_ == other.unknown_fields_;
59351 }
59352 
ParseFromArray(const void * raw,size_t size)59353 bool GetAsyncCommandRequest::ParseFromArray(const void* raw, size_t size) {
59354   unknown_fields_.clear();
59355   bool packed_error = false;
59356 
59357   ::protozero::ProtoDecoder dec(raw, size);
59358   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
59359     if (field.id() < _has_field_.size()) {
59360       _has_field_.set(field.id());
59361     }
59362     switch (field.id()) {
59363       default:
59364         field.SerializeAndAppendTo(&unknown_fields_);
59365         break;
59366     }
59367   }
59368   return !packed_error && !dec.bytes_left();
59369 }
59370 
SerializeAsString() const59371 std::string GetAsyncCommandRequest::SerializeAsString() const {
59372   ::protozero::HeapBuffered<::protozero::Message> msg;
59373   Serialize(msg.get());
59374   return msg.SerializeAsString();
59375 }
59376 
SerializeAsArray() const59377 std::vector<uint8_t> GetAsyncCommandRequest::SerializeAsArray() const {
59378   ::protozero::HeapBuffered<::protozero::Message> msg;
59379   Serialize(msg.get());
59380   return msg.SerializeAsArray();
59381 }
59382 
Serialize(::protozero::Message * msg) const59383 void GetAsyncCommandRequest::Serialize(::protozero::Message* msg) const {
59384   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59385 }
59386 
59387 
59388 ActivateTriggersResponse::ActivateTriggersResponse() = default;
59389 ActivateTriggersResponse::~ActivateTriggersResponse() = default;
59390 ActivateTriggersResponse::ActivateTriggersResponse(const ActivateTriggersResponse&) = default;
59391 ActivateTriggersResponse& ActivateTriggersResponse::operator=(const ActivateTriggersResponse&) = default;
59392 ActivateTriggersResponse::ActivateTriggersResponse(ActivateTriggersResponse&&) noexcept = default;
59393 ActivateTriggersResponse& ActivateTriggersResponse::operator=(ActivateTriggersResponse&&) = default;
59394 
operator ==(const ActivateTriggersResponse & other) const59395 bool ActivateTriggersResponse::operator==(const ActivateTriggersResponse& other) const {
59396   return unknown_fields_ == other.unknown_fields_;
59397 }
59398 
ParseFromArray(const void * raw,size_t size)59399 bool ActivateTriggersResponse::ParseFromArray(const void* raw, size_t size) {
59400   unknown_fields_.clear();
59401   bool packed_error = false;
59402 
59403   ::protozero::ProtoDecoder dec(raw, size);
59404   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
59405     if (field.id() < _has_field_.size()) {
59406       _has_field_.set(field.id());
59407     }
59408     switch (field.id()) {
59409       default:
59410         field.SerializeAndAppendTo(&unknown_fields_);
59411         break;
59412     }
59413   }
59414   return !packed_error && !dec.bytes_left();
59415 }
59416 
SerializeAsString() const59417 std::string ActivateTriggersResponse::SerializeAsString() const {
59418   ::protozero::HeapBuffered<::protozero::Message> msg;
59419   Serialize(msg.get());
59420   return msg.SerializeAsString();
59421 }
59422 
SerializeAsArray() const59423 std::vector<uint8_t> ActivateTriggersResponse::SerializeAsArray() const {
59424   ::protozero::HeapBuffered<::protozero::Message> msg;
59425   Serialize(msg.get());
59426   return msg.SerializeAsArray();
59427 }
59428 
Serialize(::protozero::Message * msg) const59429 void ActivateTriggersResponse::Serialize(::protozero::Message* msg) const {
59430   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59431 }
59432 
59433 
59434 ActivateTriggersRequest::ActivateTriggersRequest() = default;
59435 ActivateTriggersRequest::~ActivateTriggersRequest() = default;
59436 ActivateTriggersRequest::ActivateTriggersRequest(const ActivateTriggersRequest&) = default;
59437 ActivateTriggersRequest& ActivateTriggersRequest::operator=(const ActivateTriggersRequest&) = default;
59438 ActivateTriggersRequest::ActivateTriggersRequest(ActivateTriggersRequest&&) noexcept = default;
59439 ActivateTriggersRequest& ActivateTriggersRequest::operator=(ActivateTriggersRequest&&) = default;
59440 
operator ==(const ActivateTriggersRequest & other) const59441 bool ActivateTriggersRequest::operator==(const ActivateTriggersRequest& other) const {
59442   return unknown_fields_ == other.unknown_fields_
59443    && trigger_names_ == other.trigger_names_;
59444 }
59445 
ParseFromArray(const void * raw,size_t size)59446 bool ActivateTriggersRequest::ParseFromArray(const void* raw, size_t size) {
59447   trigger_names_.clear();
59448   unknown_fields_.clear();
59449   bool packed_error = false;
59450 
59451   ::protozero::ProtoDecoder dec(raw, size);
59452   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
59453     if (field.id() < _has_field_.size()) {
59454       _has_field_.set(field.id());
59455     }
59456     switch (field.id()) {
59457       case 1 /* trigger_names */:
59458         trigger_names_.emplace_back();
59459         field.get(&trigger_names_.back());
59460         break;
59461       default:
59462         field.SerializeAndAppendTo(&unknown_fields_);
59463         break;
59464     }
59465   }
59466   return !packed_error && !dec.bytes_left();
59467 }
59468 
SerializeAsString() const59469 std::string ActivateTriggersRequest::SerializeAsString() const {
59470   ::protozero::HeapBuffered<::protozero::Message> msg;
59471   Serialize(msg.get());
59472   return msg.SerializeAsString();
59473 }
59474 
SerializeAsArray() const59475 std::vector<uint8_t> ActivateTriggersRequest::SerializeAsArray() const {
59476   ::protozero::HeapBuffered<::protozero::Message> msg;
59477   Serialize(msg.get());
59478   return msg.SerializeAsArray();
59479 }
59480 
Serialize(::protozero::Message * msg) const59481 void ActivateTriggersRequest::Serialize(::protozero::Message* msg) const {
59482   // Field 1: trigger_names
59483   for (auto& it : trigger_names_) {
59484     msg->AppendString(1, it);
59485   }
59486 
59487   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59488 }
59489 
59490 
59491 NotifyDataSourceStoppedResponse::NotifyDataSourceStoppedResponse() = default;
59492 NotifyDataSourceStoppedResponse::~NotifyDataSourceStoppedResponse() = default;
59493 NotifyDataSourceStoppedResponse::NotifyDataSourceStoppedResponse(const NotifyDataSourceStoppedResponse&) = default;
59494 NotifyDataSourceStoppedResponse& NotifyDataSourceStoppedResponse::operator=(const NotifyDataSourceStoppedResponse&) = default;
59495 NotifyDataSourceStoppedResponse::NotifyDataSourceStoppedResponse(NotifyDataSourceStoppedResponse&&) noexcept = default;
59496 NotifyDataSourceStoppedResponse& NotifyDataSourceStoppedResponse::operator=(NotifyDataSourceStoppedResponse&&) = default;
59497 
operator ==(const NotifyDataSourceStoppedResponse & other) const59498 bool NotifyDataSourceStoppedResponse::operator==(const NotifyDataSourceStoppedResponse& other) const {
59499   return unknown_fields_ == other.unknown_fields_;
59500 }
59501 
ParseFromArray(const void * raw,size_t size)59502 bool NotifyDataSourceStoppedResponse::ParseFromArray(const void* raw, size_t size) {
59503   unknown_fields_.clear();
59504   bool packed_error = false;
59505 
59506   ::protozero::ProtoDecoder dec(raw, size);
59507   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
59508     if (field.id() < _has_field_.size()) {
59509       _has_field_.set(field.id());
59510     }
59511     switch (field.id()) {
59512       default:
59513         field.SerializeAndAppendTo(&unknown_fields_);
59514         break;
59515     }
59516   }
59517   return !packed_error && !dec.bytes_left();
59518 }
59519 
SerializeAsString() const59520 std::string NotifyDataSourceStoppedResponse::SerializeAsString() const {
59521   ::protozero::HeapBuffered<::protozero::Message> msg;
59522   Serialize(msg.get());
59523   return msg.SerializeAsString();
59524 }
59525 
SerializeAsArray() const59526 std::vector<uint8_t> NotifyDataSourceStoppedResponse::SerializeAsArray() const {
59527   ::protozero::HeapBuffered<::protozero::Message> msg;
59528   Serialize(msg.get());
59529   return msg.SerializeAsArray();
59530 }
59531 
Serialize(::protozero::Message * msg) const59532 void NotifyDataSourceStoppedResponse::Serialize(::protozero::Message* msg) const {
59533   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59534 }
59535 
59536 
59537 NotifyDataSourceStoppedRequest::NotifyDataSourceStoppedRequest() = default;
59538 NotifyDataSourceStoppedRequest::~NotifyDataSourceStoppedRequest() = default;
59539 NotifyDataSourceStoppedRequest::NotifyDataSourceStoppedRequest(const NotifyDataSourceStoppedRequest&) = default;
59540 NotifyDataSourceStoppedRequest& NotifyDataSourceStoppedRequest::operator=(const NotifyDataSourceStoppedRequest&) = default;
59541 NotifyDataSourceStoppedRequest::NotifyDataSourceStoppedRequest(NotifyDataSourceStoppedRequest&&) noexcept = default;
59542 NotifyDataSourceStoppedRequest& NotifyDataSourceStoppedRequest::operator=(NotifyDataSourceStoppedRequest&&) = default;
59543 
operator ==(const NotifyDataSourceStoppedRequest & other) const59544 bool NotifyDataSourceStoppedRequest::operator==(const NotifyDataSourceStoppedRequest& other) const {
59545   return unknown_fields_ == other.unknown_fields_
59546    && data_source_id_ == other.data_source_id_;
59547 }
59548 
ParseFromArray(const void * raw,size_t size)59549 bool NotifyDataSourceStoppedRequest::ParseFromArray(const void* raw, size_t size) {
59550   unknown_fields_.clear();
59551   bool packed_error = false;
59552 
59553   ::protozero::ProtoDecoder dec(raw, size);
59554   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
59555     if (field.id() < _has_field_.size()) {
59556       _has_field_.set(field.id());
59557     }
59558     switch (field.id()) {
59559       case 1 /* data_source_id */:
59560         field.get(&data_source_id_);
59561         break;
59562       default:
59563         field.SerializeAndAppendTo(&unknown_fields_);
59564         break;
59565     }
59566   }
59567   return !packed_error && !dec.bytes_left();
59568 }
59569 
SerializeAsString() const59570 std::string NotifyDataSourceStoppedRequest::SerializeAsString() const {
59571   ::protozero::HeapBuffered<::protozero::Message> msg;
59572   Serialize(msg.get());
59573   return msg.SerializeAsString();
59574 }
59575 
SerializeAsArray() const59576 std::vector<uint8_t> NotifyDataSourceStoppedRequest::SerializeAsArray() const {
59577   ::protozero::HeapBuffered<::protozero::Message> msg;
59578   Serialize(msg.get());
59579   return msg.SerializeAsArray();
59580 }
59581 
Serialize(::protozero::Message * msg) const59582 void NotifyDataSourceStoppedRequest::Serialize(::protozero::Message* msg) const {
59583   // Field 1: data_source_id
59584   if (_has_field_[1]) {
59585     msg->AppendVarInt(1, data_source_id_);
59586   }
59587 
59588   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59589 }
59590 
59591 
59592 NotifyDataSourceStartedResponse::NotifyDataSourceStartedResponse() = default;
59593 NotifyDataSourceStartedResponse::~NotifyDataSourceStartedResponse() = default;
59594 NotifyDataSourceStartedResponse::NotifyDataSourceStartedResponse(const NotifyDataSourceStartedResponse&) = default;
59595 NotifyDataSourceStartedResponse& NotifyDataSourceStartedResponse::operator=(const NotifyDataSourceStartedResponse&) = default;
59596 NotifyDataSourceStartedResponse::NotifyDataSourceStartedResponse(NotifyDataSourceStartedResponse&&) noexcept = default;
59597 NotifyDataSourceStartedResponse& NotifyDataSourceStartedResponse::operator=(NotifyDataSourceStartedResponse&&) = default;
59598 
operator ==(const NotifyDataSourceStartedResponse & other) const59599 bool NotifyDataSourceStartedResponse::operator==(const NotifyDataSourceStartedResponse& other) const {
59600   return unknown_fields_ == other.unknown_fields_;
59601 }
59602 
ParseFromArray(const void * raw,size_t size)59603 bool NotifyDataSourceStartedResponse::ParseFromArray(const void* raw, size_t size) {
59604   unknown_fields_.clear();
59605   bool packed_error = false;
59606 
59607   ::protozero::ProtoDecoder dec(raw, size);
59608   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
59609     if (field.id() < _has_field_.size()) {
59610       _has_field_.set(field.id());
59611     }
59612     switch (field.id()) {
59613       default:
59614         field.SerializeAndAppendTo(&unknown_fields_);
59615         break;
59616     }
59617   }
59618   return !packed_error && !dec.bytes_left();
59619 }
59620 
SerializeAsString() const59621 std::string NotifyDataSourceStartedResponse::SerializeAsString() const {
59622   ::protozero::HeapBuffered<::protozero::Message> msg;
59623   Serialize(msg.get());
59624   return msg.SerializeAsString();
59625 }
59626 
SerializeAsArray() const59627 std::vector<uint8_t> NotifyDataSourceStartedResponse::SerializeAsArray() const {
59628   ::protozero::HeapBuffered<::protozero::Message> msg;
59629   Serialize(msg.get());
59630   return msg.SerializeAsArray();
59631 }
59632 
Serialize(::protozero::Message * msg) const59633 void NotifyDataSourceStartedResponse::Serialize(::protozero::Message* msg) const {
59634   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59635 }
59636 
59637 
59638 NotifyDataSourceStartedRequest::NotifyDataSourceStartedRequest() = default;
59639 NotifyDataSourceStartedRequest::~NotifyDataSourceStartedRequest() = default;
59640 NotifyDataSourceStartedRequest::NotifyDataSourceStartedRequest(const NotifyDataSourceStartedRequest&) = default;
59641 NotifyDataSourceStartedRequest& NotifyDataSourceStartedRequest::operator=(const NotifyDataSourceStartedRequest&) = default;
59642 NotifyDataSourceStartedRequest::NotifyDataSourceStartedRequest(NotifyDataSourceStartedRequest&&) noexcept = default;
59643 NotifyDataSourceStartedRequest& NotifyDataSourceStartedRequest::operator=(NotifyDataSourceStartedRequest&&) = default;
59644 
operator ==(const NotifyDataSourceStartedRequest & other) const59645 bool NotifyDataSourceStartedRequest::operator==(const NotifyDataSourceStartedRequest& other) const {
59646   return unknown_fields_ == other.unknown_fields_
59647    && data_source_id_ == other.data_source_id_;
59648 }
59649 
ParseFromArray(const void * raw,size_t size)59650 bool NotifyDataSourceStartedRequest::ParseFromArray(const void* raw, size_t size) {
59651   unknown_fields_.clear();
59652   bool packed_error = false;
59653 
59654   ::protozero::ProtoDecoder dec(raw, size);
59655   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
59656     if (field.id() < _has_field_.size()) {
59657       _has_field_.set(field.id());
59658     }
59659     switch (field.id()) {
59660       case 1 /* data_source_id */:
59661         field.get(&data_source_id_);
59662         break;
59663       default:
59664         field.SerializeAndAppendTo(&unknown_fields_);
59665         break;
59666     }
59667   }
59668   return !packed_error && !dec.bytes_left();
59669 }
59670 
SerializeAsString() const59671 std::string NotifyDataSourceStartedRequest::SerializeAsString() const {
59672   ::protozero::HeapBuffered<::protozero::Message> msg;
59673   Serialize(msg.get());
59674   return msg.SerializeAsString();
59675 }
59676 
SerializeAsArray() const59677 std::vector<uint8_t> NotifyDataSourceStartedRequest::SerializeAsArray() const {
59678   ::protozero::HeapBuffered<::protozero::Message> msg;
59679   Serialize(msg.get());
59680   return msg.SerializeAsArray();
59681 }
59682 
Serialize(::protozero::Message * msg) const59683 void NotifyDataSourceStartedRequest::Serialize(::protozero::Message* msg) const {
59684   // Field 1: data_source_id
59685   if (_has_field_[1]) {
59686     msg->AppendVarInt(1, data_source_id_);
59687   }
59688 
59689   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59690 }
59691 
59692 
59693 CommitDataResponse::CommitDataResponse() = default;
59694 CommitDataResponse::~CommitDataResponse() = default;
59695 CommitDataResponse::CommitDataResponse(const CommitDataResponse&) = default;
59696 CommitDataResponse& CommitDataResponse::operator=(const CommitDataResponse&) = default;
59697 CommitDataResponse::CommitDataResponse(CommitDataResponse&&) noexcept = default;
59698 CommitDataResponse& CommitDataResponse::operator=(CommitDataResponse&&) = default;
59699 
operator ==(const CommitDataResponse & other) const59700 bool CommitDataResponse::operator==(const CommitDataResponse& other) const {
59701   return unknown_fields_ == other.unknown_fields_;
59702 }
59703 
ParseFromArray(const void * raw,size_t size)59704 bool CommitDataResponse::ParseFromArray(const void* raw, size_t size) {
59705   unknown_fields_.clear();
59706   bool packed_error = false;
59707 
59708   ::protozero::ProtoDecoder dec(raw, size);
59709   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
59710     if (field.id() < _has_field_.size()) {
59711       _has_field_.set(field.id());
59712     }
59713     switch (field.id()) {
59714       default:
59715         field.SerializeAndAppendTo(&unknown_fields_);
59716         break;
59717     }
59718   }
59719   return !packed_error && !dec.bytes_left();
59720 }
59721 
SerializeAsString() const59722 std::string CommitDataResponse::SerializeAsString() const {
59723   ::protozero::HeapBuffered<::protozero::Message> msg;
59724   Serialize(msg.get());
59725   return msg.SerializeAsString();
59726 }
59727 
SerializeAsArray() const59728 std::vector<uint8_t> CommitDataResponse::SerializeAsArray() const {
59729   ::protozero::HeapBuffered<::protozero::Message> msg;
59730   Serialize(msg.get());
59731   return msg.SerializeAsArray();
59732 }
59733 
Serialize(::protozero::Message * msg) const59734 void CommitDataResponse::Serialize(::protozero::Message* msg) const {
59735   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59736 }
59737 
59738 
59739 UnregisterTraceWriterResponse::UnregisterTraceWriterResponse() = default;
59740 UnregisterTraceWriterResponse::~UnregisterTraceWriterResponse() = default;
59741 UnregisterTraceWriterResponse::UnregisterTraceWriterResponse(const UnregisterTraceWriterResponse&) = default;
59742 UnregisterTraceWriterResponse& UnregisterTraceWriterResponse::operator=(const UnregisterTraceWriterResponse&) = default;
59743 UnregisterTraceWriterResponse::UnregisterTraceWriterResponse(UnregisterTraceWriterResponse&&) noexcept = default;
59744 UnregisterTraceWriterResponse& UnregisterTraceWriterResponse::operator=(UnregisterTraceWriterResponse&&) = default;
59745 
operator ==(const UnregisterTraceWriterResponse & other) const59746 bool UnregisterTraceWriterResponse::operator==(const UnregisterTraceWriterResponse& other) const {
59747   return unknown_fields_ == other.unknown_fields_;
59748 }
59749 
ParseFromArray(const void * raw,size_t size)59750 bool UnregisterTraceWriterResponse::ParseFromArray(const void* raw, size_t size) {
59751   unknown_fields_.clear();
59752   bool packed_error = false;
59753 
59754   ::protozero::ProtoDecoder dec(raw, size);
59755   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
59756     if (field.id() < _has_field_.size()) {
59757       _has_field_.set(field.id());
59758     }
59759     switch (field.id()) {
59760       default:
59761         field.SerializeAndAppendTo(&unknown_fields_);
59762         break;
59763     }
59764   }
59765   return !packed_error && !dec.bytes_left();
59766 }
59767 
SerializeAsString() const59768 std::string UnregisterTraceWriterResponse::SerializeAsString() const {
59769   ::protozero::HeapBuffered<::protozero::Message> msg;
59770   Serialize(msg.get());
59771   return msg.SerializeAsString();
59772 }
59773 
SerializeAsArray() const59774 std::vector<uint8_t> UnregisterTraceWriterResponse::SerializeAsArray() const {
59775   ::protozero::HeapBuffered<::protozero::Message> msg;
59776   Serialize(msg.get());
59777   return msg.SerializeAsArray();
59778 }
59779 
Serialize(::protozero::Message * msg) const59780 void UnregisterTraceWriterResponse::Serialize(::protozero::Message* msg) const {
59781   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59782 }
59783 
59784 
59785 UnregisterTraceWriterRequest::UnregisterTraceWriterRequest() = default;
59786 UnregisterTraceWriterRequest::~UnregisterTraceWriterRequest() = default;
59787 UnregisterTraceWriterRequest::UnregisterTraceWriterRequest(const UnregisterTraceWriterRequest&) = default;
59788 UnregisterTraceWriterRequest& UnregisterTraceWriterRequest::operator=(const UnregisterTraceWriterRequest&) = default;
59789 UnregisterTraceWriterRequest::UnregisterTraceWriterRequest(UnregisterTraceWriterRequest&&) noexcept = default;
59790 UnregisterTraceWriterRequest& UnregisterTraceWriterRequest::operator=(UnregisterTraceWriterRequest&&) = default;
59791 
operator ==(const UnregisterTraceWriterRequest & other) const59792 bool UnregisterTraceWriterRequest::operator==(const UnregisterTraceWriterRequest& other) const {
59793   return unknown_fields_ == other.unknown_fields_
59794    && trace_writer_id_ == other.trace_writer_id_;
59795 }
59796 
ParseFromArray(const void * raw,size_t size)59797 bool UnregisterTraceWriterRequest::ParseFromArray(const void* raw, size_t size) {
59798   unknown_fields_.clear();
59799   bool packed_error = false;
59800 
59801   ::protozero::ProtoDecoder dec(raw, size);
59802   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
59803     if (field.id() < _has_field_.size()) {
59804       _has_field_.set(field.id());
59805     }
59806     switch (field.id()) {
59807       case 1 /* trace_writer_id */:
59808         field.get(&trace_writer_id_);
59809         break;
59810       default:
59811         field.SerializeAndAppendTo(&unknown_fields_);
59812         break;
59813     }
59814   }
59815   return !packed_error && !dec.bytes_left();
59816 }
59817 
SerializeAsString() const59818 std::string UnregisterTraceWriterRequest::SerializeAsString() const {
59819   ::protozero::HeapBuffered<::protozero::Message> msg;
59820   Serialize(msg.get());
59821   return msg.SerializeAsString();
59822 }
59823 
SerializeAsArray() const59824 std::vector<uint8_t> UnregisterTraceWriterRequest::SerializeAsArray() const {
59825   ::protozero::HeapBuffered<::protozero::Message> msg;
59826   Serialize(msg.get());
59827   return msg.SerializeAsArray();
59828 }
59829 
Serialize(::protozero::Message * msg) const59830 void UnregisterTraceWriterRequest::Serialize(::protozero::Message* msg) const {
59831   // Field 1: trace_writer_id
59832   if (_has_field_[1]) {
59833     msg->AppendVarInt(1, trace_writer_id_);
59834   }
59835 
59836   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59837 }
59838 
59839 
59840 RegisterTraceWriterResponse::RegisterTraceWriterResponse() = default;
59841 RegisterTraceWriterResponse::~RegisterTraceWriterResponse() = default;
59842 RegisterTraceWriterResponse::RegisterTraceWriterResponse(const RegisterTraceWriterResponse&) = default;
59843 RegisterTraceWriterResponse& RegisterTraceWriterResponse::operator=(const RegisterTraceWriterResponse&) = default;
59844 RegisterTraceWriterResponse::RegisterTraceWriterResponse(RegisterTraceWriterResponse&&) noexcept = default;
59845 RegisterTraceWriterResponse& RegisterTraceWriterResponse::operator=(RegisterTraceWriterResponse&&) = default;
59846 
operator ==(const RegisterTraceWriterResponse & other) const59847 bool RegisterTraceWriterResponse::operator==(const RegisterTraceWriterResponse& other) const {
59848   return unknown_fields_ == other.unknown_fields_;
59849 }
59850 
ParseFromArray(const void * raw,size_t size)59851 bool RegisterTraceWriterResponse::ParseFromArray(const void* raw, size_t size) {
59852   unknown_fields_.clear();
59853   bool packed_error = false;
59854 
59855   ::protozero::ProtoDecoder dec(raw, size);
59856   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
59857     if (field.id() < _has_field_.size()) {
59858       _has_field_.set(field.id());
59859     }
59860     switch (field.id()) {
59861       default:
59862         field.SerializeAndAppendTo(&unknown_fields_);
59863         break;
59864     }
59865   }
59866   return !packed_error && !dec.bytes_left();
59867 }
59868 
SerializeAsString() const59869 std::string RegisterTraceWriterResponse::SerializeAsString() const {
59870   ::protozero::HeapBuffered<::protozero::Message> msg;
59871   Serialize(msg.get());
59872   return msg.SerializeAsString();
59873 }
59874 
SerializeAsArray() const59875 std::vector<uint8_t> RegisterTraceWriterResponse::SerializeAsArray() const {
59876   ::protozero::HeapBuffered<::protozero::Message> msg;
59877   Serialize(msg.get());
59878   return msg.SerializeAsArray();
59879 }
59880 
Serialize(::protozero::Message * msg) const59881 void RegisterTraceWriterResponse::Serialize(::protozero::Message* msg) const {
59882   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59883 }
59884 
59885 
59886 RegisterTraceWriterRequest::RegisterTraceWriterRequest() = default;
59887 RegisterTraceWriterRequest::~RegisterTraceWriterRequest() = default;
59888 RegisterTraceWriterRequest::RegisterTraceWriterRequest(const RegisterTraceWriterRequest&) = default;
59889 RegisterTraceWriterRequest& RegisterTraceWriterRequest::operator=(const RegisterTraceWriterRequest&) = default;
59890 RegisterTraceWriterRequest::RegisterTraceWriterRequest(RegisterTraceWriterRequest&&) noexcept = default;
59891 RegisterTraceWriterRequest& RegisterTraceWriterRequest::operator=(RegisterTraceWriterRequest&&) = default;
59892 
operator ==(const RegisterTraceWriterRequest & other) const59893 bool RegisterTraceWriterRequest::operator==(const RegisterTraceWriterRequest& other) const {
59894   return unknown_fields_ == other.unknown_fields_
59895    && trace_writer_id_ == other.trace_writer_id_
59896    && target_buffer_ == other.target_buffer_;
59897 }
59898 
ParseFromArray(const void * raw,size_t size)59899 bool RegisterTraceWriterRequest::ParseFromArray(const void* raw, size_t size) {
59900   unknown_fields_.clear();
59901   bool packed_error = false;
59902 
59903   ::protozero::ProtoDecoder dec(raw, size);
59904   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
59905     if (field.id() < _has_field_.size()) {
59906       _has_field_.set(field.id());
59907     }
59908     switch (field.id()) {
59909       case 1 /* trace_writer_id */:
59910         field.get(&trace_writer_id_);
59911         break;
59912       case 2 /* target_buffer */:
59913         field.get(&target_buffer_);
59914         break;
59915       default:
59916         field.SerializeAndAppendTo(&unknown_fields_);
59917         break;
59918     }
59919   }
59920   return !packed_error && !dec.bytes_left();
59921 }
59922 
SerializeAsString() const59923 std::string RegisterTraceWriterRequest::SerializeAsString() const {
59924   ::protozero::HeapBuffered<::protozero::Message> msg;
59925   Serialize(msg.get());
59926   return msg.SerializeAsString();
59927 }
59928 
SerializeAsArray() const59929 std::vector<uint8_t> RegisterTraceWriterRequest::SerializeAsArray() const {
59930   ::protozero::HeapBuffered<::protozero::Message> msg;
59931   Serialize(msg.get());
59932   return msg.SerializeAsArray();
59933 }
59934 
Serialize(::protozero::Message * msg) const59935 void RegisterTraceWriterRequest::Serialize(::protozero::Message* msg) const {
59936   // Field 1: trace_writer_id
59937   if (_has_field_[1]) {
59938     msg->AppendVarInt(1, trace_writer_id_);
59939   }
59940 
59941   // Field 2: target_buffer
59942   if (_has_field_[2]) {
59943     msg->AppendVarInt(2, target_buffer_);
59944   }
59945 
59946   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59947 }
59948 
59949 
59950 UnregisterDataSourceResponse::UnregisterDataSourceResponse() = default;
59951 UnregisterDataSourceResponse::~UnregisterDataSourceResponse() = default;
59952 UnregisterDataSourceResponse::UnregisterDataSourceResponse(const UnregisterDataSourceResponse&) = default;
59953 UnregisterDataSourceResponse& UnregisterDataSourceResponse::operator=(const UnregisterDataSourceResponse&) = default;
59954 UnregisterDataSourceResponse::UnregisterDataSourceResponse(UnregisterDataSourceResponse&&) noexcept = default;
59955 UnregisterDataSourceResponse& UnregisterDataSourceResponse::operator=(UnregisterDataSourceResponse&&) = default;
59956 
operator ==(const UnregisterDataSourceResponse & other) const59957 bool UnregisterDataSourceResponse::operator==(const UnregisterDataSourceResponse& other) const {
59958   return unknown_fields_ == other.unknown_fields_;
59959 }
59960 
ParseFromArray(const void * raw,size_t size)59961 bool UnregisterDataSourceResponse::ParseFromArray(const void* raw, size_t size) {
59962   unknown_fields_.clear();
59963   bool packed_error = false;
59964 
59965   ::protozero::ProtoDecoder dec(raw, size);
59966   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
59967     if (field.id() < _has_field_.size()) {
59968       _has_field_.set(field.id());
59969     }
59970     switch (field.id()) {
59971       default:
59972         field.SerializeAndAppendTo(&unknown_fields_);
59973         break;
59974     }
59975   }
59976   return !packed_error && !dec.bytes_left();
59977 }
59978 
SerializeAsString() const59979 std::string UnregisterDataSourceResponse::SerializeAsString() const {
59980   ::protozero::HeapBuffered<::protozero::Message> msg;
59981   Serialize(msg.get());
59982   return msg.SerializeAsString();
59983 }
59984 
SerializeAsArray() const59985 std::vector<uint8_t> UnregisterDataSourceResponse::SerializeAsArray() const {
59986   ::protozero::HeapBuffered<::protozero::Message> msg;
59987   Serialize(msg.get());
59988   return msg.SerializeAsArray();
59989 }
59990 
Serialize(::protozero::Message * msg) const59991 void UnregisterDataSourceResponse::Serialize(::protozero::Message* msg) const {
59992   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59993 }
59994 
59995 
59996 UnregisterDataSourceRequest::UnregisterDataSourceRequest() = default;
59997 UnregisterDataSourceRequest::~UnregisterDataSourceRequest() = default;
59998 UnregisterDataSourceRequest::UnregisterDataSourceRequest(const UnregisterDataSourceRequest&) = default;
59999 UnregisterDataSourceRequest& UnregisterDataSourceRequest::operator=(const UnregisterDataSourceRequest&) = default;
60000 UnregisterDataSourceRequest::UnregisterDataSourceRequest(UnregisterDataSourceRequest&&) noexcept = default;
60001 UnregisterDataSourceRequest& UnregisterDataSourceRequest::operator=(UnregisterDataSourceRequest&&) = default;
60002 
operator ==(const UnregisterDataSourceRequest & other) const60003 bool UnregisterDataSourceRequest::operator==(const UnregisterDataSourceRequest& other) const {
60004   return unknown_fields_ == other.unknown_fields_
60005    && data_source_name_ == other.data_source_name_;
60006 }
60007 
ParseFromArray(const void * raw,size_t size)60008 bool UnregisterDataSourceRequest::ParseFromArray(const void* raw, size_t size) {
60009   unknown_fields_.clear();
60010   bool packed_error = false;
60011 
60012   ::protozero::ProtoDecoder dec(raw, size);
60013   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
60014     if (field.id() < _has_field_.size()) {
60015       _has_field_.set(field.id());
60016     }
60017     switch (field.id()) {
60018       case 1 /* data_source_name */:
60019         field.get(&data_source_name_);
60020         break;
60021       default:
60022         field.SerializeAndAppendTo(&unknown_fields_);
60023         break;
60024     }
60025   }
60026   return !packed_error && !dec.bytes_left();
60027 }
60028 
SerializeAsString() const60029 std::string UnregisterDataSourceRequest::SerializeAsString() const {
60030   ::protozero::HeapBuffered<::protozero::Message> msg;
60031   Serialize(msg.get());
60032   return msg.SerializeAsString();
60033 }
60034 
SerializeAsArray() const60035 std::vector<uint8_t> UnregisterDataSourceRequest::SerializeAsArray() const {
60036   ::protozero::HeapBuffered<::protozero::Message> msg;
60037   Serialize(msg.get());
60038   return msg.SerializeAsArray();
60039 }
60040 
Serialize(::protozero::Message * msg) const60041 void UnregisterDataSourceRequest::Serialize(::protozero::Message* msg) const {
60042   // Field 1: data_source_name
60043   if (_has_field_[1]) {
60044     msg->AppendString(1, data_source_name_);
60045   }
60046 
60047   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
60048 }
60049 
60050 
60051 RegisterDataSourceResponse::RegisterDataSourceResponse() = default;
60052 RegisterDataSourceResponse::~RegisterDataSourceResponse() = default;
60053 RegisterDataSourceResponse::RegisterDataSourceResponse(const RegisterDataSourceResponse&) = default;
60054 RegisterDataSourceResponse& RegisterDataSourceResponse::operator=(const RegisterDataSourceResponse&) = default;
60055 RegisterDataSourceResponse::RegisterDataSourceResponse(RegisterDataSourceResponse&&) noexcept = default;
60056 RegisterDataSourceResponse& RegisterDataSourceResponse::operator=(RegisterDataSourceResponse&&) = default;
60057 
operator ==(const RegisterDataSourceResponse & other) const60058 bool RegisterDataSourceResponse::operator==(const RegisterDataSourceResponse& other) const {
60059   return unknown_fields_ == other.unknown_fields_
60060    && error_ == other.error_;
60061 }
60062 
ParseFromArray(const void * raw,size_t size)60063 bool RegisterDataSourceResponse::ParseFromArray(const void* raw, size_t size) {
60064   unknown_fields_.clear();
60065   bool packed_error = false;
60066 
60067   ::protozero::ProtoDecoder dec(raw, size);
60068   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
60069     if (field.id() < _has_field_.size()) {
60070       _has_field_.set(field.id());
60071     }
60072     switch (field.id()) {
60073       case 1 /* error */:
60074         field.get(&error_);
60075         break;
60076       default:
60077         field.SerializeAndAppendTo(&unknown_fields_);
60078         break;
60079     }
60080   }
60081   return !packed_error && !dec.bytes_left();
60082 }
60083 
SerializeAsString() const60084 std::string RegisterDataSourceResponse::SerializeAsString() const {
60085   ::protozero::HeapBuffered<::protozero::Message> msg;
60086   Serialize(msg.get());
60087   return msg.SerializeAsString();
60088 }
60089 
SerializeAsArray() const60090 std::vector<uint8_t> RegisterDataSourceResponse::SerializeAsArray() const {
60091   ::protozero::HeapBuffered<::protozero::Message> msg;
60092   Serialize(msg.get());
60093   return msg.SerializeAsArray();
60094 }
60095 
Serialize(::protozero::Message * msg) const60096 void RegisterDataSourceResponse::Serialize(::protozero::Message* msg) const {
60097   // Field 1: error
60098   if (_has_field_[1]) {
60099     msg->AppendString(1, error_);
60100   }
60101 
60102   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
60103 }
60104 
60105 
60106 RegisterDataSourceRequest::RegisterDataSourceRequest() = default;
60107 RegisterDataSourceRequest::~RegisterDataSourceRequest() = default;
60108 RegisterDataSourceRequest::RegisterDataSourceRequest(const RegisterDataSourceRequest&) = default;
60109 RegisterDataSourceRequest& RegisterDataSourceRequest::operator=(const RegisterDataSourceRequest&) = default;
60110 RegisterDataSourceRequest::RegisterDataSourceRequest(RegisterDataSourceRequest&&) noexcept = default;
60111 RegisterDataSourceRequest& RegisterDataSourceRequest::operator=(RegisterDataSourceRequest&&) = default;
60112 
operator ==(const RegisterDataSourceRequest & other) const60113 bool RegisterDataSourceRequest::operator==(const RegisterDataSourceRequest& other) const {
60114   return unknown_fields_ == other.unknown_fields_
60115    && data_source_descriptor_ == other.data_source_descriptor_;
60116 }
60117 
ParseFromArray(const void * raw,size_t size)60118 bool RegisterDataSourceRequest::ParseFromArray(const void* raw, size_t size) {
60119   unknown_fields_.clear();
60120   bool packed_error = false;
60121 
60122   ::protozero::ProtoDecoder dec(raw, size);
60123   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
60124     if (field.id() < _has_field_.size()) {
60125       _has_field_.set(field.id());
60126     }
60127     switch (field.id()) {
60128       case 1 /* data_source_descriptor */:
60129         (*data_source_descriptor_).ParseFromArray(field.data(), field.size());
60130         break;
60131       default:
60132         field.SerializeAndAppendTo(&unknown_fields_);
60133         break;
60134     }
60135   }
60136   return !packed_error && !dec.bytes_left();
60137 }
60138 
SerializeAsString() const60139 std::string RegisterDataSourceRequest::SerializeAsString() const {
60140   ::protozero::HeapBuffered<::protozero::Message> msg;
60141   Serialize(msg.get());
60142   return msg.SerializeAsString();
60143 }
60144 
SerializeAsArray() const60145 std::vector<uint8_t> RegisterDataSourceRequest::SerializeAsArray() const {
60146   ::protozero::HeapBuffered<::protozero::Message> msg;
60147   Serialize(msg.get());
60148   return msg.SerializeAsArray();
60149 }
60150 
Serialize(::protozero::Message * msg) const60151 void RegisterDataSourceRequest::Serialize(::protozero::Message* msg) const {
60152   // Field 1: data_source_descriptor
60153   if (_has_field_[1]) {
60154     (*data_source_descriptor_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
60155   }
60156 
60157   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
60158 }
60159 
60160 
60161 InitializeConnectionResponse::InitializeConnectionResponse() = default;
60162 InitializeConnectionResponse::~InitializeConnectionResponse() = default;
60163 InitializeConnectionResponse::InitializeConnectionResponse(const InitializeConnectionResponse&) = default;
60164 InitializeConnectionResponse& InitializeConnectionResponse::operator=(const InitializeConnectionResponse&) = default;
60165 InitializeConnectionResponse::InitializeConnectionResponse(InitializeConnectionResponse&&) noexcept = default;
60166 InitializeConnectionResponse& InitializeConnectionResponse::operator=(InitializeConnectionResponse&&) = default;
60167 
operator ==(const InitializeConnectionResponse & other) const60168 bool InitializeConnectionResponse::operator==(const InitializeConnectionResponse& other) const {
60169   return unknown_fields_ == other.unknown_fields_
60170    && using_shmem_provided_by_producer_ == other.using_shmem_provided_by_producer_
60171    && direct_smb_patching_supported_ == other.direct_smb_patching_supported_;
60172 }
60173 
ParseFromArray(const void * raw,size_t size)60174 bool InitializeConnectionResponse::ParseFromArray(const void* raw, size_t size) {
60175   unknown_fields_.clear();
60176   bool packed_error = false;
60177 
60178   ::protozero::ProtoDecoder dec(raw, size);
60179   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
60180     if (field.id() < _has_field_.size()) {
60181       _has_field_.set(field.id());
60182     }
60183     switch (field.id()) {
60184       case 1 /* using_shmem_provided_by_producer */:
60185         field.get(&using_shmem_provided_by_producer_);
60186         break;
60187       case 2 /* direct_smb_patching_supported */:
60188         field.get(&direct_smb_patching_supported_);
60189         break;
60190       default:
60191         field.SerializeAndAppendTo(&unknown_fields_);
60192         break;
60193     }
60194   }
60195   return !packed_error && !dec.bytes_left();
60196 }
60197 
SerializeAsString() const60198 std::string InitializeConnectionResponse::SerializeAsString() const {
60199   ::protozero::HeapBuffered<::protozero::Message> msg;
60200   Serialize(msg.get());
60201   return msg.SerializeAsString();
60202 }
60203 
SerializeAsArray() const60204 std::vector<uint8_t> InitializeConnectionResponse::SerializeAsArray() const {
60205   ::protozero::HeapBuffered<::protozero::Message> msg;
60206   Serialize(msg.get());
60207   return msg.SerializeAsArray();
60208 }
60209 
Serialize(::protozero::Message * msg) const60210 void InitializeConnectionResponse::Serialize(::protozero::Message* msg) const {
60211   // Field 1: using_shmem_provided_by_producer
60212   if (_has_field_[1]) {
60213     msg->AppendTinyVarInt(1, using_shmem_provided_by_producer_);
60214   }
60215 
60216   // Field 2: direct_smb_patching_supported
60217   if (_has_field_[2]) {
60218     msg->AppendTinyVarInt(2, direct_smb_patching_supported_);
60219   }
60220 
60221   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
60222 }
60223 
60224 
60225 InitializeConnectionRequest::InitializeConnectionRequest() = default;
60226 InitializeConnectionRequest::~InitializeConnectionRequest() = default;
60227 InitializeConnectionRequest::InitializeConnectionRequest(const InitializeConnectionRequest&) = default;
60228 InitializeConnectionRequest& InitializeConnectionRequest::operator=(const InitializeConnectionRequest&) = default;
60229 InitializeConnectionRequest::InitializeConnectionRequest(InitializeConnectionRequest&&) noexcept = default;
60230 InitializeConnectionRequest& InitializeConnectionRequest::operator=(InitializeConnectionRequest&&) = default;
60231 
operator ==(const InitializeConnectionRequest & other) const60232 bool InitializeConnectionRequest::operator==(const InitializeConnectionRequest& other) const {
60233   return unknown_fields_ == other.unknown_fields_
60234    && shared_memory_page_size_hint_bytes_ == other.shared_memory_page_size_hint_bytes_
60235    && shared_memory_size_hint_bytes_ == other.shared_memory_size_hint_bytes_
60236    && producer_name_ == other.producer_name_
60237    && smb_scraping_mode_ == other.smb_scraping_mode_
60238    && build_flags_ == other.build_flags_
60239    && producer_provided_shmem_ == other.producer_provided_shmem_
60240    && sdk_version_ == other.sdk_version_;
60241 }
60242 
ParseFromArray(const void * raw,size_t size)60243 bool InitializeConnectionRequest::ParseFromArray(const void* raw, size_t size) {
60244   unknown_fields_.clear();
60245   bool packed_error = false;
60246 
60247   ::protozero::ProtoDecoder dec(raw, size);
60248   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
60249     if (field.id() < _has_field_.size()) {
60250       _has_field_.set(field.id());
60251     }
60252     switch (field.id()) {
60253       case 1 /* shared_memory_page_size_hint_bytes */:
60254         field.get(&shared_memory_page_size_hint_bytes_);
60255         break;
60256       case 2 /* shared_memory_size_hint_bytes */:
60257         field.get(&shared_memory_size_hint_bytes_);
60258         break;
60259       case 3 /* producer_name */:
60260         field.get(&producer_name_);
60261         break;
60262       case 4 /* smb_scraping_mode */:
60263         field.get(&smb_scraping_mode_);
60264         break;
60265       case 5 /* build_flags */:
60266         field.get(&build_flags_);
60267         break;
60268       case 6 /* producer_provided_shmem */:
60269         field.get(&producer_provided_shmem_);
60270         break;
60271       case 8 /* sdk_version */:
60272         field.get(&sdk_version_);
60273         break;
60274       default:
60275         field.SerializeAndAppendTo(&unknown_fields_);
60276         break;
60277     }
60278   }
60279   return !packed_error && !dec.bytes_left();
60280 }
60281 
SerializeAsString() const60282 std::string InitializeConnectionRequest::SerializeAsString() const {
60283   ::protozero::HeapBuffered<::protozero::Message> msg;
60284   Serialize(msg.get());
60285   return msg.SerializeAsString();
60286 }
60287 
SerializeAsArray() const60288 std::vector<uint8_t> InitializeConnectionRequest::SerializeAsArray() const {
60289   ::protozero::HeapBuffered<::protozero::Message> msg;
60290   Serialize(msg.get());
60291   return msg.SerializeAsArray();
60292 }
60293 
Serialize(::protozero::Message * msg) const60294 void InitializeConnectionRequest::Serialize(::protozero::Message* msg) const {
60295   // Field 1: shared_memory_page_size_hint_bytes
60296   if (_has_field_[1]) {
60297     msg->AppendVarInt(1, shared_memory_page_size_hint_bytes_);
60298   }
60299 
60300   // Field 2: shared_memory_size_hint_bytes
60301   if (_has_field_[2]) {
60302     msg->AppendVarInt(2, shared_memory_size_hint_bytes_);
60303   }
60304 
60305   // Field 3: producer_name
60306   if (_has_field_[3]) {
60307     msg->AppendString(3, producer_name_);
60308   }
60309 
60310   // Field 4: smb_scraping_mode
60311   if (_has_field_[4]) {
60312     msg->AppendVarInt(4, smb_scraping_mode_);
60313   }
60314 
60315   // Field 5: build_flags
60316   if (_has_field_[5]) {
60317     msg->AppendVarInt(5, build_flags_);
60318   }
60319 
60320   // Field 6: producer_provided_shmem
60321   if (_has_field_[6]) {
60322     msg->AppendTinyVarInt(6, producer_provided_shmem_);
60323   }
60324 
60325   // Field 8: sdk_version
60326   if (_has_field_[8]) {
60327     msg->AppendString(8, sdk_version_);
60328   }
60329 
60330   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
60331 }
60332 
60333 }  // namespace perfetto
60334 }  // namespace protos
60335 }  // namespace gen
60336 #if defined(__GNUC__) || defined(__clang__)
60337 #pragma GCC diagnostic pop
60338 #endif
60339 // gen_amalgamated begin source: gen/protos/perfetto/ipc/wire_protocol.gen.cc
60340 // gen_amalgamated begin header: gen/protos/perfetto/ipc/wire_protocol.gen.h
60341 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
60342 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_WIRE_PROTOCOL_PROTO_CPP_H_
60343 #define PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_WIRE_PROTOCOL_PROTO_CPP_H_
60344 
60345 #include <stdint.h>
60346 #include <bitset>
60347 #include <vector>
60348 #include <string>
60349 #include <type_traits>
60350 
60351 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
60352 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
60353 // gen_amalgamated expanded: #include "perfetto/base/export.h"
60354 
60355 namespace perfetto {
60356 namespace protos {
60357 namespace gen {
60358 class IPCFrame;
60359 class IPCFrame_RequestError;
60360 class IPCFrame_InvokeMethodReply;
60361 class IPCFrame_InvokeMethod;
60362 class IPCFrame_BindServiceReply;
60363 class IPCFrame_BindServiceReply_MethodInfo;
60364 class IPCFrame_BindService;
60365 }  // namespace perfetto
60366 }  // namespace protos
60367 }  // namespace gen
60368 
60369 namespace protozero {
60370 class Message;
60371 }  // namespace protozero
60372 
60373 namespace perfetto {
60374 namespace protos {
60375 namespace gen {
60376 
60377 class PERFETTO_EXPORT IPCFrame : public ::protozero::CppMessageObj {
60378  public:
60379   using BindService = IPCFrame_BindService;
60380   using BindServiceReply = IPCFrame_BindServiceReply;
60381   using InvokeMethod = IPCFrame_InvokeMethod;
60382   using InvokeMethodReply = IPCFrame_InvokeMethodReply;
60383   using RequestError = IPCFrame_RequestError;
60384   enum FieldNumbers {
60385     kRequestIdFieldNumber = 2,
60386     kMsgBindServiceFieldNumber = 3,
60387     kMsgBindServiceReplyFieldNumber = 4,
60388     kMsgInvokeMethodFieldNumber = 5,
60389     kMsgInvokeMethodReplyFieldNumber = 6,
60390     kMsgRequestErrorFieldNumber = 7,
60391     kDataForTestingFieldNumber = 1,
60392   };
60393 
60394   IPCFrame();
60395   ~IPCFrame() override;
60396   IPCFrame(IPCFrame&&) noexcept;
60397   IPCFrame& operator=(IPCFrame&&);
60398   IPCFrame(const IPCFrame&);
60399   IPCFrame& operator=(const IPCFrame&);
60400   bool operator==(const IPCFrame&) const;
operator !=(const IPCFrame & other) const60401   bool operator!=(const IPCFrame& other) const { return !(*this == other); }
60402 
60403   bool ParseFromArray(const void*, size_t) override;
60404   std::string SerializeAsString() const override;
60405   std::vector<uint8_t> SerializeAsArray() const override;
60406   void Serialize(::protozero::Message*) const;
60407 
has_request_id() const60408   bool has_request_id() const { return _has_field_[2]; }
request_id() const60409   uint64_t request_id() const { return request_id_; }
set_request_id(uint64_t value)60410   void set_request_id(uint64_t value) { request_id_ = value; _has_field_.set(2); }
60411 
has_msg_bind_service() const60412   bool has_msg_bind_service() const { return _has_field_[3]; }
msg_bind_service() const60413   const IPCFrame_BindService& msg_bind_service() const { return *msg_bind_service_; }
mutable_msg_bind_service()60414   IPCFrame_BindService* mutable_msg_bind_service() { _has_field_.set(3); return msg_bind_service_.get(); }
60415 
has_msg_bind_service_reply() const60416   bool has_msg_bind_service_reply() const { return _has_field_[4]; }
msg_bind_service_reply() const60417   const IPCFrame_BindServiceReply& msg_bind_service_reply() const { return *msg_bind_service_reply_; }
mutable_msg_bind_service_reply()60418   IPCFrame_BindServiceReply* mutable_msg_bind_service_reply() { _has_field_.set(4); return msg_bind_service_reply_.get(); }
60419 
has_msg_invoke_method() const60420   bool has_msg_invoke_method() const { return _has_field_[5]; }
msg_invoke_method() const60421   const IPCFrame_InvokeMethod& msg_invoke_method() const { return *msg_invoke_method_; }
mutable_msg_invoke_method()60422   IPCFrame_InvokeMethod* mutable_msg_invoke_method() { _has_field_.set(5); return msg_invoke_method_.get(); }
60423 
has_msg_invoke_method_reply() const60424   bool has_msg_invoke_method_reply() const { return _has_field_[6]; }
msg_invoke_method_reply() const60425   const IPCFrame_InvokeMethodReply& msg_invoke_method_reply() const { return *msg_invoke_method_reply_; }
mutable_msg_invoke_method_reply()60426   IPCFrame_InvokeMethodReply* mutable_msg_invoke_method_reply() { _has_field_.set(6); return msg_invoke_method_reply_.get(); }
60427 
has_msg_request_error() const60428   bool has_msg_request_error() const { return _has_field_[7]; }
msg_request_error() const60429   const IPCFrame_RequestError& msg_request_error() const { return *msg_request_error_; }
mutable_msg_request_error()60430   IPCFrame_RequestError* mutable_msg_request_error() { _has_field_.set(7); return msg_request_error_.get(); }
60431 
data_for_testing() const60432   const std::vector<std::string>& data_for_testing() const { return data_for_testing_; }
mutable_data_for_testing()60433   std::vector<std::string>* mutable_data_for_testing() { return &data_for_testing_; }
data_for_testing_size() const60434   int data_for_testing_size() const { return static_cast<int>(data_for_testing_.size()); }
clear_data_for_testing()60435   void clear_data_for_testing() { data_for_testing_.clear(); }
add_data_for_testing(std::string value)60436   void add_data_for_testing(std::string value) { data_for_testing_.emplace_back(value); }
add_data_for_testing()60437   std::string* add_data_for_testing() { data_for_testing_.emplace_back(); return &data_for_testing_.back(); }
60438 
60439  private:
60440   uint64_t request_id_{};
60441   ::protozero::CopyablePtr<IPCFrame_BindService> msg_bind_service_;
60442   ::protozero::CopyablePtr<IPCFrame_BindServiceReply> msg_bind_service_reply_;
60443   ::protozero::CopyablePtr<IPCFrame_InvokeMethod> msg_invoke_method_;
60444   ::protozero::CopyablePtr<IPCFrame_InvokeMethodReply> msg_invoke_method_reply_;
60445   ::protozero::CopyablePtr<IPCFrame_RequestError> msg_request_error_;
60446   std::vector<std::string> data_for_testing_;
60447 
60448   // Allows to preserve unknown protobuf fields for compatibility
60449   // with future versions of .proto files.
60450   std::string unknown_fields_;
60451 
60452   std::bitset<8> _has_field_{};
60453 };
60454 
60455 
60456 class PERFETTO_EXPORT IPCFrame_RequestError : public ::protozero::CppMessageObj {
60457  public:
60458   enum FieldNumbers {
60459     kErrorFieldNumber = 1,
60460   };
60461 
60462   IPCFrame_RequestError();
60463   ~IPCFrame_RequestError() override;
60464   IPCFrame_RequestError(IPCFrame_RequestError&&) noexcept;
60465   IPCFrame_RequestError& operator=(IPCFrame_RequestError&&);
60466   IPCFrame_RequestError(const IPCFrame_RequestError&);
60467   IPCFrame_RequestError& operator=(const IPCFrame_RequestError&);
60468   bool operator==(const IPCFrame_RequestError&) const;
operator !=(const IPCFrame_RequestError & other) const60469   bool operator!=(const IPCFrame_RequestError& other) const { return !(*this == other); }
60470 
60471   bool ParseFromArray(const void*, size_t) override;
60472   std::string SerializeAsString() const override;
60473   std::vector<uint8_t> SerializeAsArray() const override;
60474   void Serialize(::protozero::Message*) const;
60475 
has_error() const60476   bool has_error() const { return _has_field_[1]; }
error() const60477   const std::string& error() const { return error_; }
set_error(const std::string & value)60478   void set_error(const std::string& value) { error_ = value; _has_field_.set(1); }
60479 
60480  private:
60481   std::string error_{};
60482 
60483   // Allows to preserve unknown protobuf fields for compatibility
60484   // with future versions of .proto files.
60485   std::string unknown_fields_;
60486 
60487   std::bitset<2> _has_field_{};
60488 };
60489 
60490 
60491 class PERFETTO_EXPORT IPCFrame_InvokeMethodReply : public ::protozero::CppMessageObj {
60492  public:
60493   enum FieldNumbers {
60494     kSuccessFieldNumber = 1,
60495     kHasMoreFieldNumber = 2,
60496     kReplyProtoFieldNumber = 3,
60497   };
60498 
60499   IPCFrame_InvokeMethodReply();
60500   ~IPCFrame_InvokeMethodReply() override;
60501   IPCFrame_InvokeMethodReply(IPCFrame_InvokeMethodReply&&) noexcept;
60502   IPCFrame_InvokeMethodReply& operator=(IPCFrame_InvokeMethodReply&&);
60503   IPCFrame_InvokeMethodReply(const IPCFrame_InvokeMethodReply&);
60504   IPCFrame_InvokeMethodReply& operator=(const IPCFrame_InvokeMethodReply&);
60505   bool operator==(const IPCFrame_InvokeMethodReply&) const;
operator !=(const IPCFrame_InvokeMethodReply & other) const60506   bool operator!=(const IPCFrame_InvokeMethodReply& other) const { return !(*this == other); }
60507 
60508   bool ParseFromArray(const void*, size_t) override;
60509   std::string SerializeAsString() const override;
60510   std::vector<uint8_t> SerializeAsArray() const override;
60511   void Serialize(::protozero::Message*) const;
60512 
has_success() const60513   bool has_success() const { return _has_field_[1]; }
success() const60514   bool success() const { return success_; }
set_success(bool value)60515   void set_success(bool value) { success_ = value; _has_field_.set(1); }
60516 
has_has_more() const60517   bool has_has_more() const { return _has_field_[2]; }
has_more() const60518   bool has_more() const { return has_more_; }
set_has_more(bool value)60519   void set_has_more(bool value) { has_more_ = value; _has_field_.set(2); }
60520 
has_reply_proto() const60521   bool has_reply_proto() const { return _has_field_[3]; }
reply_proto() const60522   const std::string& reply_proto() const { return reply_proto_; }
set_reply_proto(const std::string & value)60523   void set_reply_proto(const std::string& value) { reply_proto_ = value; _has_field_.set(3); }
set_reply_proto(const void * p,size_t s)60524   void set_reply_proto(const void* p, size_t s) { reply_proto_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(3); }
60525 
60526  private:
60527   bool success_{};
60528   bool has_more_{};
60529   std::string reply_proto_{};
60530 
60531   // Allows to preserve unknown protobuf fields for compatibility
60532   // with future versions of .proto files.
60533   std::string unknown_fields_;
60534 
60535   std::bitset<4> _has_field_{};
60536 };
60537 
60538 
60539 class PERFETTO_EXPORT IPCFrame_InvokeMethod : public ::protozero::CppMessageObj {
60540  public:
60541   enum FieldNumbers {
60542     kServiceIdFieldNumber = 1,
60543     kMethodIdFieldNumber = 2,
60544     kArgsProtoFieldNumber = 3,
60545     kDropReplyFieldNumber = 4,
60546   };
60547 
60548   IPCFrame_InvokeMethod();
60549   ~IPCFrame_InvokeMethod() override;
60550   IPCFrame_InvokeMethod(IPCFrame_InvokeMethod&&) noexcept;
60551   IPCFrame_InvokeMethod& operator=(IPCFrame_InvokeMethod&&);
60552   IPCFrame_InvokeMethod(const IPCFrame_InvokeMethod&);
60553   IPCFrame_InvokeMethod& operator=(const IPCFrame_InvokeMethod&);
60554   bool operator==(const IPCFrame_InvokeMethod&) const;
operator !=(const IPCFrame_InvokeMethod & other) const60555   bool operator!=(const IPCFrame_InvokeMethod& other) const { return !(*this == other); }
60556 
60557   bool ParseFromArray(const void*, size_t) override;
60558   std::string SerializeAsString() const override;
60559   std::vector<uint8_t> SerializeAsArray() const override;
60560   void Serialize(::protozero::Message*) const;
60561 
has_service_id() const60562   bool has_service_id() const { return _has_field_[1]; }
service_id() const60563   uint32_t service_id() const { return service_id_; }
set_service_id(uint32_t value)60564   void set_service_id(uint32_t value) { service_id_ = value; _has_field_.set(1); }
60565 
has_method_id() const60566   bool has_method_id() const { return _has_field_[2]; }
method_id() const60567   uint32_t method_id() const { return method_id_; }
set_method_id(uint32_t value)60568   void set_method_id(uint32_t value) { method_id_ = value; _has_field_.set(2); }
60569 
has_args_proto() const60570   bool has_args_proto() const { return _has_field_[3]; }
args_proto() const60571   const std::string& args_proto() const { return args_proto_; }
set_args_proto(const std::string & value)60572   void set_args_proto(const std::string& value) { args_proto_ = value; _has_field_.set(3); }
set_args_proto(const void * p,size_t s)60573   void set_args_proto(const void* p, size_t s) { args_proto_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(3); }
60574 
has_drop_reply() const60575   bool has_drop_reply() const { return _has_field_[4]; }
drop_reply() const60576   bool drop_reply() const { return drop_reply_; }
set_drop_reply(bool value)60577   void set_drop_reply(bool value) { drop_reply_ = value; _has_field_.set(4); }
60578 
60579  private:
60580   uint32_t service_id_{};
60581   uint32_t method_id_{};
60582   std::string args_proto_{};
60583   bool drop_reply_{};
60584 
60585   // Allows to preserve unknown protobuf fields for compatibility
60586   // with future versions of .proto files.
60587   std::string unknown_fields_;
60588 
60589   std::bitset<5> _has_field_{};
60590 };
60591 
60592 
60593 class PERFETTO_EXPORT IPCFrame_BindServiceReply : public ::protozero::CppMessageObj {
60594  public:
60595   using MethodInfo = IPCFrame_BindServiceReply_MethodInfo;
60596   enum FieldNumbers {
60597     kSuccessFieldNumber = 1,
60598     kServiceIdFieldNumber = 2,
60599     kMethodsFieldNumber = 3,
60600   };
60601 
60602   IPCFrame_BindServiceReply();
60603   ~IPCFrame_BindServiceReply() override;
60604   IPCFrame_BindServiceReply(IPCFrame_BindServiceReply&&) noexcept;
60605   IPCFrame_BindServiceReply& operator=(IPCFrame_BindServiceReply&&);
60606   IPCFrame_BindServiceReply(const IPCFrame_BindServiceReply&);
60607   IPCFrame_BindServiceReply& operator=(const IPCFrame_BindServiceReply&);
60608   bool operator==(const IPCFrame_BindServiceReply&) const;
operator !=(const IPCFrame_BindServiceReply & other) const60609   bool operator!=(const IPCFrame_BindServiceReply& other) const { return !(*this == other); }
60610 
60611   bool ParseFromArray(const void*, size_t) override;
60612   std::string SerializeAsString() const override;
60613   std::vector<uint8_t> SerializeAsArray() const override;
60614   void Serialize(::protozero::Message*) const;
60615 
has_success() const60616   bool has_success() const { return _has_field_[1]; }
success() const60617   bool success() const { return success_; }
set_success(bool value)60618   void set_success(bool value) { success_ = value; _has_field_.set(1); }
60619 
has_service_id() const60620   bool has_service_id() const { return _has_field_[2]; }
service_id() const60621   uint32_t service_id() const { return service_id_; }
set_service_id(uint32_t value)60622   void set_service_id(uint32_t value) { service_id_ = value; _has_field_.set(2); }
60623 
methods() const60624   const std::vector<IPCFrame_BindServiceReply_MethodInfo>& methods() const { return methods_; }
mutable_methods()60625   std::vector<IPCFrame_BindServiceReply_MethodInfo>* mutable_methods() { return &methods_; }
60626   int methods_size() const;
60627   void clear_methods();
60628   IPCFrame_BindServiceReply_MethodInfo* add_methods();
60629 
60630  private:
60631   bool success_{};
60632   uint32_t service_id_{};
60633   std::vector<IPCFrame_BindServiceReply_MethodInfo> methods_;
60634 
60635   // Allows to preserve unknown protobuf fields for compatibility
60636   // with future versions of .proto files.
60637   std::string unknown_fields_;
60638 
60639   std::bitset<4> _has_field_{};
60640 };
60641 
60642 
60643 class PERFETTO_EXPORT IPCFrame_BindServiceReply_MethodInfo : public ::protozero::CppMessageObj {
60644  public:
60645   enum FieldNumbers {
60646     kIdFieldNumber = 1,
60647     kNameFieldNumber = 2,
60648   };
60649 
60650   IPCFrame_BindServiceReply_MethodInfo();
60651   ~IPCFrame_BindServiceReply_MethodInfo() override;
60652   IPCFrame_BindServiceReply_MethodInfo(IPCFrame_BindServiceReply_MethodInfo&&) noexcept;
60653   IPCFrame_BindServiceReply_MethodInfo& operator=(IPCFrame_BindServiceReply_MethodInfo&&);
60654   IPCFrame_BindServiceReply_MethodInfo(const IPCFrame_BindServiceReply_MethodInfo&);
60655   IPCFrame_BindServiceReply_MethodInfo& operator=(const IPCFrame_BindServiceReply_MethodInfo&);
60656   bool operator==(const IPCFrame_BindServiceReply_MethodInfo&) const;
operator !=(const IPCFrame_BindServiceReply_MethodInfo & other) const60657   bool operator!=(const IPCFrame_BindServiceReply_MethodInfo& other) const { return !(*this == other); }
60658 
60659   bool ParseFromArray(const void*, size_t) override;
60660   std::string SerializeAsString() const override;
60661   std::vector<uint8_t> SerializeAsArray() const override;
60662   void Serialize(::protozero::Message*) const;
60663 
has_id() const60664   bool has_id() const { return _has_field_[1]; }
id() const60665   uint32_t id() const { return id_; }
set_id(uint32_t value)60666   void set_id(uint32_t value) { id_ = value; _has_field_.set(1); }
60667 
has_name() const60668   bool has_name() const { return _has_field_[2]; }
name() const60669   const std::string& name() const { return name_; }
set_name(const std::string & value)60670   void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
60671 
60672  private:
60673   uint32_t id_{};
60674   std::string name_{};
60675 
60676   // Allows to preserve unknown protobuf fields for compatibility
60677   // with future versions of .proto files.
60678   std::string unknown_fields_;
60679 
60680   std::bitset<3> _has_field_{};
60681 };
60682 
60683 
60684 class PERFETTO_EXPORT IPCFrame_BindService : public ::protozero::CppMessageObj {
60685  public:
60686   enum FieldNumbers {
60687     kServiceNameFieldNumber = 1,
60688   };
60689 
60690   IPCFrame_BindService();
60691   ~IPCFrame_BindService() override;
60692   IPCFrame_BindService(IPCFrame_BindService&&) noexcept;
60693   IPCFrame_BindService& operator=(IPCFrame_BindService&&);
60694   IPCFrame_BindService(const IPCFrame_BindService&);
60695   IPCFrame_BindService& operator=(const IPCFrame_BindService&);
60696   bool operator==(const IPCFrame_BindService&) const;
operator !=(const IPCFrame_BindService & other) const60697   bool operator!=(const IPCFrame_BindService& other) const { return !(*this == other); }
60698 
60699   bool ParseFromArray(const void*, size_t) override;
60700   std::string SerializeAsString() const override;
60701   std::vector<uint8_t> SerializeAsArray() const override;
60702   void Serialize(::protozero::Message*) const;
60703 
has_service_name() const60704   bool has_service_name() const { return _has_field_[1]; }
service_name() const60705   const std::string& service_name() const { return service_name_; }
set_service_name(const std::string & value)60706   void set_service_name(const std::string& value) { service_name_ = value; _has_field_.set(1); }
60707 
60708  private:
60709   std::string service_name_{};
60710 
60711   // Allows to preserve unknown protobuf fields for compatibility
60712   // with future versions of .proto files.
60713   std::string unknown_fields_;
60714 
60715   std::bitset<2> _has_field_{};
60716 };
60717 
60718 }  // namespace perfetto
60719 }  // namespace protos
60720 }  // namespace gen
60721 
60722 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_WIRE_PROTOCOL_PROTO_CPP_H_
60723 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
60724 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
60725 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
60726 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
60727 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
60728 #if defined(__GNUC__) || defined(__clang__)
60729 #pragma GCC diagnostic push
60730 #pragma GCC diagnostic ignored "-Wfloat-equal"
60731 #endif
60732 // gen_amalgamated expanded: #include "protos/perfetto/ipc/wire_protocol.gen.h"
60733 
60734 namespace perfetto {
60735 namespace protos {
60736 namespace gen {
60737 
60738 IPCFrame::IPCFrame() = default;
60739 IPCFrame::~IPCFrame() = default;
60740 IPCFrame::IPCFrame(const IPCFrame&) = default;
60741 IPCFrame& IPCFrame::operator=(const IPCFrame&) = default;
60742 IPCFrame::IPCFrame(IPCFrame&&) noexcept = default;
60743 IPCFrame& IPCFrame::operator=(IPCFrame&&) = default;
60744 
operator ==(const IPCFrame & other) const60745 bool IPCFrame::operator==(const IPCFrame& other) const {
60746   return unknown_fields_ == other.unknown_fields_
60747    && request_id_ == other.request_id_
60748    && msg_bind_service_ == other.msg_bind_service_
60749    && msg_bind_service_reply_ == other.msg_bind_service_reply_
60750    && msg_invoke_method_ == other.msg_invoke_method_
60751    && msg_invoke_method_reply_ == other.msg_invoke_method_reply_
60752    && msg_request_error_ == other.msg_request_error_
60753    && data_for_testing_ == other.data_for_testing_;
60754 }
60755 
ParseFromArray(const void * raw,size_t size)60756 bool IPCFrame::ParseFromArray(const void* raw, size_t size) {
60757   data_for_testing_.clear();
60758   unknown_fields_.clear();
60759   bool packed_error = false;
60760 
60761   ::protozero::ProtoDecoder dec(raw, size);
60762   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
60763     if (field.id() < _has_field_.size()) {
60764       _has_field_.set(field.id());
60765     }
60766     switch (field.id()) {
60767       case 2 /* request_id */:
60768         field.get(&request_id_);
60769         break;
60770       case 3 /* msg_bind_service */:
60771         (*msg_bind_service_).ParseFromArray(field.data(), field.size());
60772         break;
60773       case 4 /* msg_bind_service_reply */:
60774         (*msg_bind_service_reply_).ParseFromArray(field.data(), field.size());
60775         break;
60776       case 5 /* msg_invoke_method */:
60777         (*msg_invoke_method_).ParseFromArray(field.data(), field.size());
60778         break;
60779       case 6 /* msg_invoke_method_reply */:
60780         (*msg_invoke_method_reply_).ParseFromArray(field.data(), field.size());
60781         break;
60782       case 7 /* msg_request_error */:
60783         (*msg_request_error_).ParseFromArray(field.data(), field.size());
60784         break;
60785       case 1 /* data_for_testing */:
60786         data_for_testing_.emplace_back();
60787         field.get(&data_for_testing_.back());
60788         break;
60789       default:
60790         field.SerializeAndAppendTo(&unknown_fields_);
60791         break;
60792     }
60793   }
60794   return !packed_error && !dec.bytes_left();
60795 }
60796 
SerializeAsString() const60797 std::string IPCFrame::SerializeAsString() const {
60798   ::protozero::HeapBuffered<::protozero::Message> msg;
60799   Serialize(msg.get());
60800   return msg.SerializeAsString();
60801 }
60802 
SerializeAsArray() const60803 std::vector<uint8_t> IPCFrame::SerializeAsArray() const {
60804   ::protozero::HeapBuffered<::protozero::Message> msg;
60805   Serialize(msg.get());
60806   return msg.SerializeAsArray();
60807 }
60808 
Serialize(::protozero::Message * msg) const60809 void IPCFrame::Serialize(::protozero::Message* msg) const {
60810   // Field 2: request_id
60811   if (_has_field_[2]) {
60812     msg->AppendVarInt(2, request_id_);
60813   }
60814 
60815   // Field 3: msg_bind_service
60816   if (_has_field_[3]) {
60817     (*msg_bind_service_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
60818   }
60819 
60820   // Field 4: msg_bind_service_reply
60821   if (_has_field_[4]) {
60822     (*msg_bind_service_reply_).Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
60823   }
60824 
60825   // Field 5: msg_invoke_method
60826   if (_has_field_[5]) {
60827     (*msg_invoke_method_).Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
60828   }
60829 
60830   // Field 6: msg_invoke_method_reply
60831   if (_has_field_[6]) {
60832     (*msg_invoke_method_reply_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
60833   }
60834 
60835   // Field 7: msg_request_error
60836   if (_has_field_[7]) {
60837     (*msg_request_error_).Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
60838   }
60839 
60840   // Field 1: data_for_testing
60841   for (auto& it : data_for_testing_) {
60842     msg->AppendString(1, it);
60843   }
60844 
60845   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
60846 }
60847 
60848 
60849 IPCFrame_RequestError::IPCFrame_RequestError() = default;
60850 IPCFrame_RequestError::~IPCFrame_RequestError() = default;
60851 IPCFrame_RequestError::IPCFrame_RequestError(const IPCFrame_RequestError&) = default;
60852 IPCFrame_RequestError& IPCFrame_RequestError::operator=(const IPCFrame_RequestError&) = default;
60853 IPCFrame_RequestError::IPCFrame_RequestError(IPCFrame_RequestError&&) noexcept = default;
60854 IPCFrame_RequestError& IPCFrame_RequestError::operator=(IPCFrame_RequestError&&) = default;
60855 
operator ==(const IPCFrame_RequestError & other) const60856 bool IPCFrame_RequestError::operator==(const IPCFrame_RequestError& other) const {
60857   return unknown_fields_ == other.unknown_fields_
60858    && error_ == other.error_;
60859 }
60860 
ParseFromArray(const void * raw,size_t size)60861 bool IPCFrame_RequestError::ParseFromArray(const void* raw, size_t size) {
60862   unknown_fields_.clear();
60863   bool packed_error = false;
60864 
60865   ::protozero::ProtoDecoder dec(raw, size);
60866   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
60867     if (field.id() < _has_field_.size()) {
60868       _has_field_.set(field.id());
60869     }
60870     switch (field.id()) {
60871       case 1 /* error */:
60872         field.get(&error_);
60873         break;
60874       default:
60875         field.SerializeAndAppendTo(&unknown_fields_);
60876         break;
60877     }
60878   }
60879   return !packed_error && !dec.bytes_left();
60880 }
60881 
SerializeAsString() const60882 std::string IPCFrame_RequestError::SerializeAsString() const {
60883   ::protozero::HeapBuffered<::protozero::Message> msg;
60884   Serialize(msg.get());
60885   return msg.SerializeAsString();
60886 }
60887 
SerializeAsArray() const60888 std::vector<uint8_t> IPCFrame_RequestError::SerializeAsArray() const {
60889   ::protozero::HeapBuffered<::protozero::Message> msg;
60890   Serialize(msg.get());
60891   return msg.SerializeAsArray();
60892 }
60893 
Serialize(::protozero::Message * msg) const60894 void IPCFrame_RequestError::Serialize(::protozero::Message* msg) const {
60895   // Field 1: error
60896   if (_has_field_[1]) {
60897     msg->AppendString(1, error_);
60898   }
60899 
60900   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
60901 }
60902 
60903 
60904 IPCFrame_InvokeMethodReply::IPCFrame_InvokeMethodReply() = default;
60905 IPCFrame_InvokeMethodReply::~IPCFrame_InvokeMethodReply() = default;
60906 IPCFrame_InvokeMethodReply::IPCFrame_InvokeMethodReply(const IPCFrame_InvokeMethodReply&) = default;
60907 IPCFrame_InvokeMethodReply& IPCFrame_InvokeMethodReply::operator=(const IPCFrame_InvokeMethodReply&) = default;
60908 IPCFrame_InvokeMethodReply::IPCFrame_InvokeMethodReply(IPCFrame_InvokeMethodReply&&) noexcept = default;
60909 IPCFrame_InvokeMethodReply& IPCFrame_InvokeMethodReply::operator=(IPCFrame_InvokeMethodReply&&) = default;
60910 
operator ==(const IPCFrame_InvokeMethodReply & other) const60911 bool IPCFrame_InvokeMethodReply::operator==(const IPCFrame_InvokeMethodReply& other) const {
60912   return unknown_fields_ == other.unknown_fields_
60913    && success_ == other.success_
60914    && has_more_ == other.has_more_
60915    && reply_proto_ == other.reply_proto_;
60916 }
60917 
ParseFromArray(const void * raw,size_t size)60918 bool IPCFrame_InvokeMethodReply::ParseFromArray(const void* raw, size_t size) {
60919   unknown_fields_.clear();
60920   bool packed_error = false;
60921 
60922   ::protozero::ProtoDecoder dec(raw, size);
60923   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
60924     if (field.id() < _has_field_.size()) {
60925       _has_field_.set(field.id());
60926     }
60927     switch (field.id()) {
60928       case 1 /* success */:
60929         field.get(&success_);
60930         break;
60931       case 2 /* has_more */:
60932         field.get(&has_more_);
60933         break;
60934       case 3 /* reply_proto */:
60935         field.get(&reply_proto_);
60936         break;
60937       default:
60938         field.SerializeAndAppendTo(&unknown_fields_);
60939         break;
60940     }
60941   }
60942   return !packed_error && !dec.bytes_left();
60943 }
60944 
SerializeAsString() const60945 std::string IPCFrame_InvokeMethodReply::SerializeAsString() const {
60946   ::protozero::HeapBuffered<::protozero::Message> msg;
60947   Serialize(msg.get());
60948   return msg.SerializeAsString();
60949 }
60950 
SerializeAsArray() const60951 std::vector<uint8_t> IPCFrame_InvokeMethodReply::SerializeAsArray() const {
60952   ::protozero::HeapBuffered<::protozero::Message> msg;
60953   Serialize(msg.get());
60954   return msg.SerializeAsArray();
60955 }
60956 
Serialize(::protozero::Message * msg) const60957 void IPCFrame_InvokeMethodReply::Serialize(::protozero::Message* msg) const {
60958   // Field 1: success
60959   if (_has_field_[1]) {
60960     msg->AppendTinyVarInt(1, success_);
60961   }
60962 
60963   // Field 2: has_more
60964   if (_has_field_[2]) {
60965     msg->AppendTinyVarInt(2, has_more_);
60966   }
60967 
60968   // Field 3: reply_proto
60969   if (_has_field_[3]) {
60970     msg->AppendString(3, reply_proto_);
60971   }
60972 
60973   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
60974 }
60975 
60976 
60977 IPCFrame_InvokeMethod::IPCFrame_InvokeMethod() = default;
60978 IPCFrame_InvokeMethod::~IPCFrame_InvokeMethod() = default;
60979 IPCFrame_InvokeMethod::IPCFrame_InvokeMethod(const IPCFrame_InvokeMethod&) = default;
60980 IPCFrame_InvokeMethod& IPCFrame_InvokeMethod::operator=(const IPCFrame_InvokeMethod&) = default;
60981 IPCFrame_InvokeMethod::IPCFrame_InvokeMethod(IPCFrame_InvokeMethod&&) noexcept = default;
60982 IPCFrame_InvokeMethod& IPCFrame_InvokeMethod::operator=(IPCFrame_InvokeMethod&&) = default;
60983 
operator ==(const IPCFrame_InvokeMethod & other) const60984 bool IPCFrame_InvokeMethod::operator==(const IPCFrame_InvokeMethod& other) const {
60985   return unknown_fields_ == other.unknown_fields_
60986    && service_id_ == other.service_id_
60987    && method_id_ == other.method_id_
60988    && args_proto_ == other.args_proto_
60989    && drop_reply_ == other.drop_reply_;
60990 }
60991 
ParseFromArray(const void * raw,size_t size)60992 bool IPCFrame_InvokeMethod::ParseFromArray(const void* raw, size_t size) {
60993   unknown_fields_.clear();
60994   bool packed_error = false;
60995 
60996   ::protozero::ProtoDecoder dec(raw, size);
60997   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
60998     if (field.id() < _has_field_.size()) {
60999       _has_field_.set(field.id());
61000     }
61001     switch (field.id()) {
61002       case 1 /* service_id */:
61003         field.get(&service_id_);
61004         break;
61005       case 2 /* method_id */:
61006         field.get(&method_id_);
61007         break;
61008       case 3 /* args_proto */:
61009         field.get(&args_proto_);
61010         break;
61011       case 4 /* drop_reply */:
61012         field.get(&drop_reply_);
61013         break;
61014       default:
61015         field.SerializeAndAppendTo(&unknown_fields_);
61016         break;
61017     }
61018   }
61019   return !packed_error && !dec.bytes_left();
61020 }
61021 
SerializeAsString() const61022 std::string IPCFrame_InvokeMethod::SerializeAsString() const {
61023   ::protozero::HeapBuffered<::protozero::Message> msg;
61024   Serialize(msg.get());
61025   return msg.SerializeAsString();
61026 }
61027 
SerializeAsArray() const61028 std::vector<uint8_t> IPCFrame_InvokeMethod::SerializeAsArray() const {
61029   ::protozero::HeapBuffered<::protozero::Message> msg;
61030   Serialize(msg.get());
61031   return msg.SerializeAsArray();
61032 }
61033 
Serialize(::protozero::Message * msg) const61034 void IPCFrame_InvokeMethod::Serialize(::protozero::Message* msg) const {
61035   // Field 1: service_id
61036   if (_has_field_[1]) {
61037     msg->AppendVarInt(1, service_id_);
61038   }
61039 
61040   // Field 2: method_id
61041   if (_has_field_[2]) {
61042     msg->AppendVarInt(2, method_id_);
61043   }
61044 
61045   // Field 3: args_proto
61046   if (_has_field_[3]) {
61047     msg->AppendString(3, args_proto_);
61048   }
61049 
61050   // Field 4: drop_reply
61051   if (_has_field_[4]) {
61052     msg->AppendTinyVarInt(4, drop_reply_);
61053   }
61054 
61055   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
61056 }
61057 
61058 
61059 IPCFrame_BindServiceReply::IPCFrame_BindServiceReply() = default;
61060 IPCFrame_BindServiceReply::~IPCFrame_BindServiceReply() = default;
61061 IPCFrame_BindServiceReply::IPCFrame_BindServiceReply(const IPCFrame_BindServiceReply&) = default;
61062 IPCFrame_BindServiceReply& IPCFrame_BindServiceReply::operator=(const IPCFrame_BindServiceReply&) = default;
61063 IPCFrame_BindServiceReply::IPCFrame_BindServiceReply(IPCFrame_BindServiceReply&&) noexcept = default;
61064 IPCFrame_BindServiceReply& IPCFrame_BindServiceReply::operator=(IPCFrame_BindServiceReply&&) = default;
61065 
operator ==(const IPCFrame_BindServiceReply & other) const61066 bool IPCFrame_BindServiceReply::operator==(const IPCFrame_BindServiceReply& other) const {
61067   return unknown_fields_ == other.unknown_fields_
61068    && success_ == other.success_
61069    && service_id_ == other.service_id_
61070    && methods_ == other.methods_;
61071 }
61072 
methods_size() const61073 int IPCFrame_BindServiceReply::methods_size() const { return static_cast<int>(methods_.size()); }
clear_methods()61074 void IPCFrame_BindServiceReply::clear_methods() { methods_.clear(); }
add_methods()61075 IPCFrame_BindServiceReply_MethodInfo* IPCFrame_BindServiceReply::add_methods() { methods_.emplace_back(); return &methods_.back(); }
ParseFromArray(const void * raw,size_t size)61076 bool IPCFrame_BindServiceReply::ParseFromArray(const void* raw, size_t size) {
61077   methods_.clear();
61078   unknown_fields_.clear();
61079   bool packed_error = false;
61080 
61081   ::protozero::ProtoDecoder dec(raw, size);
61082   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
61083     if (field.id() < _has_field_.size()) {
61084       _has_field_.set(field.id());
61085     }
61086     switch (field.id()) {
61087       case 1 /* success */:
61088         field.get(&success_);
61089         break;
61090       case 2 /* service_id */:
61091         field.get(&service_id_);
61092         break;
61093       case 3 /* methods */:
61094         methods_.emplace_back();
61095         methods_.back().ParseFromArray(field.data(), field.size());
61096         break;
61097       default:
61098         field.SerializeAndAppendTo(&unknown_fields_);
61099         break;
61100     }
61101   }
61102   return !packed_error && !dec.bytes_left();
61103 }
61104 
SerializeAsString() const61105 std::string IPCFrame_BindServiceReply::SerializeAsString() const {
61106   ::protozero::HeapBuffered<::protozero::Message> msg;
61107   Serialize(msg.get());
61108   return msg.SerializeAsString();
61109 }
61110 
SerializeAsArray() const61111 std::vector<uint8_t> IPCFrame_BindServiceReply::SerializeAsArray() const {
61112   ::protozero::HeapBuffered<::protozero::Message> msg;
61113   Serialize(msg.get());
61114   return msg.SerializeAsArray();
61115 }
61116 
Serialize(::protozero::Message * msg) const61117 void IPCFrame_BindServiceReply::Serialize(::protozero::Message* msg) const {
61118   // Field 1: success
61119   if (_has_field_[1]) {
61120     msg->AppendTinyVarInt(1, success_);
61121   }
61122 
61123   // Field 2: service_id
61124   if (_has_field_[2]) {
61125     msg->AppendVarInt(2, service_id_);
61126   }
61127 
61128   // Field 3: methods
61129   for (auto& it : methods_) {
61130     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
61131   }
61132 
61133   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
61134 }
61135 
61136 
61137 IPCFrame_BindServiceReply_MethodInfo::IPCFrame_BindServiceReply_MethodInfo() = default;
61138 IPCFrame_BindServiceReply_MethodInfo::~IPCFrame_BindServiceReply_MethodInfo() = default;
61139 IPCFrame_BindServiceReply_MethodInfo::IPCFrame_BindServiceReply_MethodInfo(const IPCFrame_BindServiceReply_MethodInfo&) = default;
61140 IPCFrame_BindServiceReply_MethodInfo& IPCFrame_BindServiceReply_MethodInfo::operator=(const IPCFrame_BindServiceReply_MethodInfo&) = default;
61141 IPCFrame_BindServiceReply_MethodInfo::IPCFrame_BindServiceReply_MethodInfo(IPCFrame_BindServiceReply_MethodInfo&&) noexcept = default;
61142 IPCFrame_BindServiceReply_MethodInfo& IPCFrame_BindServiceReply_MethodInfo::operator=(IPCFrame_BindServiceReply_MethodInfo&&) = default;
61143 
operator ==(const IPCFrame_BindServiceReply_MethodInfo & other) const61144 bool IPCFrame_BindServiceReply_MethodInfo::operator==(const IPCFrame_BindServiceReply_MethodInfo& other) const {
61145   return unknown_fields_ == other.unknown_fields_
61146    && id_ == other.id_
61147    && name_ == other.name_;
61148 }
61149 
ParseFromArray(const void * raw,size_t size)61150 bool IPCFrame_BindServiceReply_MethodInfo::ParseFromArray(const void* raw, size_t size) {
61151   unknown_fields_.clear();
61152   bool packed_error = false;
61153 
61154   ::protozero::ProtoDecoder dec(raw, size);
61155   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
61156     if (field.id() < _has_field_.size()) {
61157       _has_field_.set(field.id());
61158     }
61159     switch (field.id()) {
61160       case 1 /* id */:
61161         field.get(&id_);
61162         break;
61163       case 2 /* name */:
61164         field.get(&name_);
61165         break;
61166       default:
61167         field.SerializeAndAppendTo(&unknown_fields_);
61168         break;
61169     }
61170   }
61171   return !packed_error && !dec.bytes_left();
61172 }
61173 
SerializeAsString() const61174 std::string IPCFrame_BindServiceReply_MethodInfo::SerializeAsString() const {
61175   ::protozero::HeapBuffered<::protozero::Message> msg;
61176   Serialize(msg.get());
61177   return msg.SerializeAsString();
61178 }
61179 
SerializeAsArray() const61180 std::vector<uint8_t> IPCFrame_BindServiceReply_MethodInfo::SerializeAsArray() const {
61181   ::protozero::HeapBuffered<::protozero::Message> msg;
61182   Serialize(msg.get());
61183   return msg.SerializeAsArray();
61184 }
61185 
Serialize(::protozero::Message * msg) const61186 void IPCFrame_BindServiceReply_MethodInfo::Serialize(::protozero::Message* msg) const {
61187   // Field 1: id
61188   if (_has_field_[1]) {
61189     msg->AppendVarInt(1, id_);
61190   }
61191 
61192   // Field 2: name
61193   if (_has_field_[2]) {
61194     msg->AppendString(2, name_);
61195   }
61196 
61197   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
61198 }
61199 
61200 
61201 IPCFrame_BindService::IPCFrame_BindService() = default;
61202 IPCFrame_BindService::~IPCFrame_BindService() = default;
61203 IPCFrame_BindService::IPCFrame_BindService(const IPCFrame_BindService&) = default;
61204 IPCFrame_BindService& IPCFrame_BindService::operator=(const IPCFrame_BindService&) = default;
61205 IPCFrame_BindService::IPCFrame_BindService(IPCFrame_BindService&&) noexcept = default;
61206 IPCFrame_BindService& IPCFrame_BindService::operator=(IPCFrame_BindService&&) = default;
61207 
operator ==(const IPCFrame_BindService & other) const61208 bool IPCFrame_BindService::operator==(const IPCFrame_BindService& other) const {
61209   return unknown_fields_ == other.unknown_fields_
61210    && service_name_ == other.service_name_;
61211 }
61212 
ParseFromArray(const void * raw,size_t size)61213 bool IPCFrame_BindService::ParseFromArray(const void* raw, size_t size) {
61214   unknown_fields_.clear();
61215   bool packed_error = false;
61216 
61217   ::protozero::ProtoDecoder dec(raw, size);
61218   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
61219     if (field.id() < _has_field_.size()) {
61220       _has_field_.set(field.id());
61221     }
61222     switch (field.id()) {
61223       case 1 /* service_name */:
61224         field.get(&service_name_);
61225         break;
61226       default:
61227         field.SerializeAndAppendTo(&unknown_fields_);
61228         break;
61229     }
61230   }
61231   return !packed_error && !dec.bytes_left();
61232 }
61233 
SerializeAsString() const61234 std::string IPCFrame_BindService::SerializeAsString() const {
61235   ::protozero::HeapBuffered<::protozero::Message> msg;
61236   Serialize(msg.get());
61237   return msg.SerializeAsString();
61238 }
61239 
SerializeAsArray() const61240 std::vector<uint8_t> IPCFrame_BindService::SerializeAsArray() const {
61241   ::protozero::HeapBuffered<::protozero::Message> msg;
61242   Serialize(msg.get());
61243   return msg.SerializeAsArray();
61244 }
61245 
Serialize(::protozero::Message * msg) const61246 void IPCFrame_BindService::Serialize(::protozero::Message* msg) const {
61247   // Field 1: service_name
61248   if (_has_field_[1]) {
61249     msg->AppendString(1, service_name_);
61250   }
61251 
61252   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
61253 }
61254 
61255 }  // namespace perfetto
61256 }  // namespace protos
61257 }  // namespace gen
61258 #if defined(__GNUC__) || defined(__clang__)
61259 #pragma GCC diagnostic pop
61260 #endif
61261 // gen_amalgamated begin source: src/base/unix_socket.cc
61262 // gen_amalgamated begin header: include/perfetto/ext/base/unix_socket.h
61263 /*
61264  * Copyright (C) 2017 The Android Open Source Project
61265  *
61266  * Licensed under the Apache License, Version 2.0 (the "License");
61267  * you may not use this file except in compliance with the License.
61268  * You may obtain a copy of the License at
61269  *
61270  *      http://www.apache.org/licenses/LICENSE-2.0
61271  *
61272  * Unless required by applicable law or agreed to in writing, software
61273  * distributed under the License is distributed on an "AS IS" BASIS,
61274  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
61275  * See the License for the specific language governing permissions and
61276  * limitations under the License.
61277  */
61278 
61279 #ifndef INCLUDE_PERFETTO_EXT_BASE_UNIX_SOCKET_H_
61280 #define INCLUDE_PERFETTO_EXT_BASE_UNIX_SOCKET_H_
61281 
61282 #include <stdint.h>
61283 #include <sys/types.h>
61284 
61285 #include <memory>
61286 #include <string>
61287 
61288 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
61289 // gen_amalgamated expanded: #include "perfetto/base/export.h"
61290 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
61291 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
61292 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
61293 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
61294 
61295 struct msghdr;
61296 
61297 namespace perfetto {
61298 namespace base {
61299 
61300 // Define the SocketHandle and ScopedSocketHandle types.
61301 // On POSIX OSes, a SocketHandle is really just an int (a file descriptor).
61302 // On Windows, sockets are have their own type (SOCKET) which is neither a
61303 // HANDLE nor an int. However Windows SOCKET(s) can have a event HANDLE attached
61304 // to them (which in Perfetto is a PlatformHandle), and that can be used in
61305 // WaitForMultipleObjects, hence in base::TaskRunner.AddFileDescriptorWatch().
61306 
61307 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
61308 // uintptr_t really reads as SOCKET here (Windows headers typedef to that).
61309 // As usual we don't just use SOCKET here to avoid leaking Windows.h includes
61310 // in our headers.
61311 using SocketHandle = uintptr_t;  // SOCKET
61312 int CloseSocket(SocketHandle);   // A wrapper around ::closesocket().
61313 using ScopedSocketHandle =
61314     ScopedResource<SocketHandle, CloseSocket, static_cast<SocketHandle>(-1)>;
61315 #else
61316 using SocketHandle = int;
61317 using ScopedSocketHandle = ScopedFile;
61318 #endif
61319 
61320 class TaskRunner;
61321 
61322 // Use arbitrarily high values to avoid that some code accidentally ends up
61323 // assuming that these enum values match the sysroot's SOCK_xxx defines rather
61324 // than using GetSockType() / GetSockFamily().
61325 enum class SockType { kStream = 100, kDgram, kSeqPacket };
61326 enum class SockFamily { kUnix = 200, kInet, kInet6 };
61327 
61328 // Controls the getsockopt(SO_PEERCRED) behavior, which allows to obtain the
61329 // peer credentials.
61330 enum class SockPeerCredMode {
61331   // Obtain the peer credentials immediatley after connection and cache them.
61332   kReadOnConnect = 0,
61333 
61334   // Don't read peer credentials at all. Calls to peer_uid()/peer_pid() will
61335   // hit a DCHECK and return kInvalidUid/Pid in release builds.
61336   kIgnore = 1,
61337 
61338 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
61339   kDefault = kIgnore,
61340 #else
61341   kDefault = kReadOnConnect,
61342 #endif
61343 };
61344 
61345 // UnixSocketRaw is a basic wrapper around sockets. It exposes wrapper
61346 // methods that take care of most common pitfalls (e.g., marking fd as
61347 // O_CLOEXEC, avoiding SIGPIPE, properly handling partial writes). It is used as
61348 // a building block for the more sophisticated UnixSocket class which depends
61349 // on base::TaskRunner.
61350 class UnixSocketRaw {
61351  public:
61352   // Creates a new unconnected unix socket.
61353   static UnixSocketRaw CreateMayFail(SockFamily family, SockType type);
61354 
61355 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
61356   // Crates a pair of connected sockets.
61357   static std::pair<UnixSocketRaw, UnixSocketRaw> CreatePairPosix(SockFamily,
61358                                                                  SockType);
61359 #endif
61360 
61361   // Creates an uninitialized unix socket.
61362   UnixSocketRaw();
61363 
61364   // Creates a unix socket adopting an existing file descriptor. This is
61365   // typically used to inherit fds from init via environment variables.
61366   UnixSocketRaw(ScopedSocketHandle, SockFamily, SockType);
61367 
61368   ~UnixSocketRaw() = default;
61369   UnixSocketRaw(UnixSocketRaw&&) noexcept = default;
61370   UnixSocketRaw& operator=(UnixSocketRaw&&) = default;
61371 
61372   bool Bind(const std::string& socket_name);
61373   bool Listen();
61374   bool Connect(const std::string& socket_name);
61375   bool SetTxTimeout(uint32_t timeout_ms);
61376   bool SetRxTimeout(uint32_t timeout_ms);
61377   void Shutdown();
61378   void SetBlocking(bool);
61379   void DcheckIsBlocking(bool expected) const;  // No-op on release and Win.
61380   void RetainOnExec();
type() const61381   SockType type() const { return type_; }
family() const61382   SockFamily family() const { return family_; }
fd() const61383   SocketHandle fd() const { return *fd_; }
operator bool() const61384   explicit operator bool() const { return !!fd_; }
61385 
61386   // This is the handle that passed to TaskRunner.AddFileDescriptorWatch().
61387   // On UNIX this is just the socket FD. On Windows, we need to create a
61388   // dedicated event object.
watch_handle() const61389   PlatformHandle watch_handle() const {
61390 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
61391     return *event_handle_;
61392 #else
61393     return *fd_;
61394 #endif
61395   }
61396 
ReleaseFd()61397   ScopedSocketHandle ReleaseFd() { return std::move(fd_); }
61398 
61399   // |send_fds| and |num_fds| are ignored on Windows.
61400   ssize_t Send(const void* msg,
61401                size_t len,
61402                const int* send_fds = nullptr,
61403                size_t num_fds = 0);
61404 
61405   // |fd_vec| and |max_files| are ignored on Windows.
61406   ssize_t Receive(void* msg,
61407                   size_t len,
61408                   ScopedFile* fd_vec = nullptr,
61409                   size_t max_files = 0);
61410 
61411 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
61412   // UNIX-specific helpers to deal with SCM_RIGHTS.
61413 
61414   // Re-enter sendmsg until all the data has been sent or an error occurs.
61415   // TODO(fmayer): Figure out how to do timeouts here for heapprofd.
61416   ssize_t SendMsgAllPosix(struct msghdr* msg);
61417 
61418   // Exposed for testing only.
61419   // Update msghdr so subsequent sendmsg will send data that remains after n
61420   // bytes have already been sent.
61421   static void ShiftMsgHdrPosix(size_t n, struct msghdr* msg);
61422 #endif
61423 
61424  private:
61425   UnixSocketRaw(SockFamily, SockType);
61426 
61427   UnixSocketRaw(const UnixSocketRaw&) = delete;
61428   UnixSocketRaw& operator=(const UnixSocketRaw&) = delete;
61429 
61430   ScopedSocketHandle fd_;
61431 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
61432   ScopedPlatformHandle event_handle_;
61433 #endif
61434   SockFamily family_ = SockFamily::kUnix;
61435   SockType type_ = SockType::kStream;
61436 };
61437 
61438 // A non-blocking UNIX domain socket. Allows also to transfer file descriptors.
61439 // None of the methods in this class are blocking.
61440 // The main design goal is making strong guarantees on the EventListener
61441 // callbacks, in order to avoid ending in some undefined state.
61442 // In case of any error it will aggressively just shut down the socket and
61443 // notify the failure with OnConnect(false) or OnDisconnect() depending on the
61444 // state of the socket (see below).
61445 // EventListener callbacks stop happening as soon as the instance is destroyed.
61446 //
61447 // Lifecycle of a client socket:
61448 //
61449 //                           Connect()
61450 //                               |
61451 //            +------------------+------------------+
61452 //            | (success)                           | (failure or Shutdown())
61453 //            V                                     V
61454 //     OnConnect(true)                         OnConnect(false)
61455 //            |
61456 //            V
61457 //    OnDataAvailable()
61458 //            |
61459 //            V
61460 //     OnDisconnect()  (failure or shutdown)
61461 //
61462 //
61463 // Lifecycle of a server socket:
61464 //
61465 //                          Listen()  --> returns false in case of errors.
61466 //                             |
61467 //                             V
61468 //              OnNewIncomingConnection(new_socket)
61469 //
61470 //          (|new_socket| inherits the same EventListener)
61471 //                             |
61472 //                             V
61473 //                     OnDataAvailable()
61474 //                             | (failure or Shutdown())
61475 //                             V
61476 //                       OnDisconnect()
61477 class PERFETTO_EXPORT UnixSocket {
61478  public:
61479   class EventListener {
61480    public:
61481     virtual ~EventListener();
61482 
61483     // After Listen().
61484     virtual void OnNewIncomingConnection(
61485         UnixSocket* self,
61486         std::unique_ptr<UnixSocket> new_connection);
61487 
61488     // After Connect(), whether successful or not.
61489     virtual void OnConnect(UnixSocket* self, bool connected);
61490 
61491     // After a successful Connect() or OnNewIncomingConnection(). Either the
61492     // other endpoint did disconnect or some other error happened.
61493     virtual void OnDisconnect(UnixSocket* self);
61494 
61495     // Whenever there is data available to Receive(). Note that spurious FD
61496     // watch events are possible, so it is possible that Receive() soon after
61497     // OnDataAvailable() returns 0 (just ignore those).
61498     virtual void OnDataAvailable(UnixSocket* self);
61499   };
61500 
61501   enum class State {
61502     kDisconnected = 0,  // Failed connection, peer disconnection or Shutdown().
61503     kConnecting,  // Soon after Connect(), before it either succeeds or fails.
61504     kConnected,   // After a successful Connect().
61505     kListening    // After Listen(), until Shutdown().
61506   };
61507 
61508   // Creates a socket and starts listening. If SockFamily::kUnix and
61509   // |socket_name| starts with a '@', an abstract UNIX dmoain socket will be
61510   // created instead of a filesystem-linked UNIX socket (Linux/Android only).
61511   // If SockFamily::kInet, |socket_name| is host:port (e.g., "1.2.3.4:8000").
61512   // If SockFamily::kInet6, |socket_name| is [host]:port (e.g., "[::1]:8000").
61513   // Returns nullptr if the socket creation or bind fails. If listening fails,
61514   // (e.g. if another socket with the same name is already listening) the
61515   // returned socket will have is_listening() == false.
61516   static std::unique_ptr<UnixSocket> Listen(const std::string& socket_name,
61517                                             EventListener*,
61518                                             TaskRunner*,
61519                                             SockFamily,
61520                                             SockType);
61521 
61522   // Attaches to a pre-existing socket. The socket must have been created in
61523   // SOCK_STREAM mode and the caller must have called bind() on it.
61524   static std::unique_ptr<UnixSocket> Listen(ScopedSocketHandle,
61525                                             EventListener*,
61526                                             TaskRunner*,
61527                                             SockFamily,
61528                                             SockType);
61529 
61530   // Creates a Unix domain socket and connects to the listening endpoint.
61531   // Returns always an instance. EventListener::OnConnect(bool success) will
61532   // be called always, whether the connection succeeded or not.
61533   static std::unique_ptr<UnixSocket> Connect(
61534       const std::string& socket_name,
61535       EventListener*,
61536       TaskRunner*,
61537       SockFamily,
61538       SockType,
61539       SockPeerCredMode = SockPeerCredMode::kDefault);
61540 
61541   // Constructs a UnixSocket using the given connected socket.
61542   static std::unique_ptr<UnixSocket> AdoptConnected(
61543       ScopedSocketHandle,
61544       EventListener*,
61545       TaskRunner*,
61546       SockFamily,
61547       SockType,
61548       SockPeerCredMode = SockPeerCredMode::kDefault);
61549 
61550   UnixSocket(const UnixSocket&) = delete;
61551   UnixSocket& operator=(const UnixSocket&) = delete;
61552   // Cannot be easily moved because of tasks from the FileDescriptorWatch.
61553   UnixSocket(UnixSocket&&) = delete;
61554   UnixSocket& operator=(UnixSocket&&) = delete;
61555 
61556   // This class gives the hard guarantee that no callback is called on the
61557   // passed EventListener immediately after the object has been destroyed.
61558   // Any queued callback will be silently dropped.
61559   ~UnixSocket();
61560 
61561   // Shuts down the current connection, if any. If the socket was Listen()-ing,
61562   // stops listening. The socket goes back to kNotInitialized state, so it can
61563   // be reused with Listen() or Connect().
61564   void Shutdown(bool notify);
61565 
SetTxTimeout(uint32_t timeout_ms)61566   void SetTxTimeout(uint32_t timeout_ms) {
61567     PERFETTO_CHECK(sock_raw_.SetTxTimeout(timeout_ms));
61568   }
SetRxTimeout(uint32_t timeout_ms)61569   void SetRxTimeout(uint32_t timeout_ms) {
61570     PERFETTO_CHECK(sock_raw_.SetRxTimeout(timeout_ms));
61571   }
61572   // Returns true is the message was queued, false if there was no space in the
61573   // output buffer, in which case the client should retry or give up.
61574   // If any other error happens the socket will be shutdown and
61575   // EventListener::OnDisconnect() will be called.
61576   // If the socket is not connected, Send() will just return false.
61577   // Does not append a null string terminator to msg in any case.
61578   bool Send(const void* msg, size_t len, const int* send_fds, size_t num_fds);
61579 
Send(const void * msg,size_t len,int send_fd=-1)61580   inline bool Send(const void* msg, size_t len, int send_fd = -1) {
61581     if (send_fd != -1)
61582       return Send(msg, len, &send_fd, 1);
61583     return Send(msg, len, nullptr, 0);
61584   }
61585 
Send(const std::string & msg)61586   inline bool Send(const std::string& msg) {
61587     return Send(msg.c_str(), msg.size() + 1, -1);
61588   }
61589 
61590   // Returns the number of bytes (<= |len|) written in |msg| or 0 if there
61591   // is no data in the buffer to read or an error occurs (in which case a
61592   // EventListener::OnDisconnect() will follow).
61593   // If the ScopedFile pointer is not null and a FD is received, it moves the
61594   // received FD into that. If a FD is received but the ScopedFile pointer is
61595   // null, the FD will be automatically closed.
61596   size_t Receive(void* msg, size_t len, ScopedFile*, size_t max_files = 1);
61597 
Receive(void * msg,size_t len)61598   inline size_t Receive(void* msg, size_t len) {
61599     return Receive(msg, len, nullptr, 0);
61600   }
61601 
61602   // Only for tests. This is slower than Receive() as it requires a heap
61603   // allocation and a copy for the std::string. Guarantees that the returned
61604   // string is null terminated even if the underlying message sent by the peer
61605   // is not.
61606   std::string ReceiveString(size_t max_length = 1024);
61607 
is_connected() const61608   bool is_connected() const { return state_ == State::kConnected; }
is_listening() const61609   bool is_listening() const { return state_ == State::kListening; }
fd() const61610   SocketHandle fd() const { return sock_raw_.fd(); }
61611 
61612   // User ID of the peer, as returned by the kernel. If the client disconnects
61613   // and the socket goes into the kDisconnected state, it retains the uid of
61614   // the last peer.
61615 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
peer_uid_posix(bool skip_check_for_testing=false) const61616   uid_t peer_uid_posix(bool skip_check_for_testing = false) const {
61617     PERFETTO_DCHECK((!is_listening() && peer_uid_ != kInvalidUid) ||
61618                     skip_check_for_testing);
61619 
61620     return peer_uid_;
61621   }
61622 #endif
61623 
61624 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
61625     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
61626   // Process ID of the peer, as returned by the kernel. If the client
61627   // disconnects and the socket goes into the kDisconnected state, it
61628   // retains the pid of the last peer.
61629   //
61630   // This is only available on Linux / Android.
peer_pid_linux(bool skip_check_for_testing=false) const61631   pid_t peer_pid_linux(bool skip_check_for_testing = false) const {
61632     PERFETTO_DCHECK((!is_listening() && peer_pid_ != kInvalidPid) ||
61633                     skip_check_for_testing);
61634     return peer_pid_;
61635   }
61636 #endif
61637 
61638   // This makes the UnixSocket unusable.
61639   UnixSocketRaw ReleaseSocket();
61640 
61641  private:
61642   UnixSocket(EventListener*,
61643              TaskRunner*,
61644              SockFamily,
61645              SockType,
61646              SockPeerCredMode);
61647   UnixSocket(EventListener*,
61648              TaskRunner*,
61649              ScopedSocketHandle,
61650              State,
61651              SockFamily,
61652              SockType,
61653              SockPeerCredMode);
61654 
61655   // Called once by the corresponding public static factory methods.
61656   void DoConnect(const std::string& socket_name);
61657 
61658 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
61659   void ReadPeerCredentialsPosix();
61660 #endif
61661 
61662   void OnEvent();
61663   void NotifyConnectionState(bool success);
61664 
61665   UnixSocketRaw sock_raw_;
61666   State state_ = State::kDisconnected;
61667   SockPeerCredMode peer_cred_mode_ = SockPeerCredMode::kDefault;
61668 
61669 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
61670   uid_t peer_uid_ = kInvalidUid;
61671 #endif
61672 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
61673     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
61674   pid_t peer_pid_ = kInvalidPid;
61675 #endif
61676   EventListener* const event_listener_;
61677   TaskRunner* const task_runner_;
61678   WeakPtrFactory<UnixSocket> weak_ptr_factory_;  // Keep last.
61679 };
61680 
61681 }  // namespace base
61682 }  // namespace perfetto
61683 
61684 #endif  // INCLUDE_PERFETTO_EXT_BASE_UNIX_SOCKET_H_
61685 /*
61686  * Copyright (C) 2017 The Android Open Source Project
61687  *
61688  * Licensed under the Apache License, Version 2.0 (the "License");
61689  * you may not use this file except in compliance with the License.
61690  * You may obtain a copy of the License at
61691  *
61692  *      http://www.apache.org/licenses/LICENSE-2.0
61693  *
61694  * Unless required by applicable law or agreed to in writing, software
61695  * distributed under the License is distributed on an "AS IS" BASIS,
61696  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
61697  * See the License for the specific language governing permissions and
61698  * limitations under the License.
61699  */
61700 
61701 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
61702 
61703 #include <errno.h>
61704 #include <fcntl.h>
61705 #include <stdlib.h>
61706 #include <string.h>
61707 #include <sys/stat.h>
61708 #include <sys/types.h>
61709 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
61710 
61711 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
61712 // The include order matters on these three Windows header groups.
61713 #include <Windows.h>
61714 
61715 #include <WS2tcpip.h>
61716 #include <WinSock2.h>
61717 
61718 #include <afunix.h>
61719 #else
61720 #include <netdb.h>
61721 #include <netinet/in.h>
61722 #include <netinet/tcp.h>
61723 #include <sys/socket.h>
61724 #include <sys/un.h>
61725 #include <unistd.h>
61726 #endif
61727 
61728 #if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
61729 #include <sys/ucred.h>
61730 #endif
61731 
61732 #include <algorithm>
61733 #include <memory>
61734 
61735 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
61736 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
61737 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
61738 // gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
61739 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
61740 
61741 namespace perfetto {
61742 namespace base {
61743 
61744 // The CMSG_* macros use NULL instead of nullptr.
61745 // Note: MSVC doesn't have #pragma GCC diagnostic, hence the if __GNUC__.
61746 #if defined(__GNUC__) && !PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
61747 #pragma GCC diagnostic push
61748 #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
61749 #endif
61750 
61751 namespace {
61752 
61753 // MSG_NOSIGNAL is not supported on Mac OS X, but in that case the socket is
61754 // created with SO_NOSIGPIPE (See InitializeSocket()).
61755 // On Windows this does't apply as signals don't exist.
61756 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
61757 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
61758 constexpr int kNoSigPipe = 0;
61759 #else
61760 constexpr int kNoSigPipe = MSG_NOSIGNAL;
61761 #endif
61762 
61763 // Android takes an int instead of socklen_t for the control buffer size.
61764 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
61765 using CBufLenType = size_t;
61766 #else
61767 using CBufLenType = socklen_t;
61768 #endif
61769 
61770 // A wrapper around variable-size sockaddr structs.
61771 // This is solving the following problem: when calling connect() or bind(), the
61772 // caller needs to take care to allocate the right struct (sockaddr_un for
61773 // AF_UNIX, sockaddr_in for AF_INET).   Those structs have different sizes and,
61774 // more importantly, are bigger than the base struct sockaddr.
61775 struct SockaddrAny {
SockaddrAnyperfetto::base::__anon2fbee880c611::SockaddrAny61776   SockaddrAny() : size() {}
SockaddrAnyperfetto::base::__anon2fbee880c611::SockaddrAny61777   SockaddrAny(const void* addr, socklen_t sz)
61778       : data(new char[static_cast<size_t>(sz)]), size(sz) {
61779     memcpy(data.get(), addr, static_cast<size_t>(size));
61780   }
61781 
addrperfetto::base::__anon2fbee880c611::SockaddrAny61782   const struct sockaddr* addr() const {
61783     return reinterpret_cast<const struct sockaddr*>(data.get());
61784   }
61785 
61786   std::unique_ptr<char[]> data;
61787   socklen_t size;
61788 };
61789 
GetSockFamily(SockFamily family)61790 inline int GetSockFamily(SockFamily family) {
61791   switch (family) {
61792     case SockFamily::kUnix:
61793       return AF_UNIX;
61794     case SockFamily::kInet:
61795       return AF_INET;
61796     case SockFamily::kInet6:
61797       return AF_INET6;
61798   }
61799   PERFETTO_CHECK(false);  // For GCC.
61800 }
61801 
GetSockType(SockType type)61802 inline int GetSockType(SockType type) {
61803 #ifdef SOCK_CLOEXEC
61804   constexpr int kSockCloExec = SOCK_CLOEXEC;
61805 #else
61806   constexpr int kSockCloExec = 0;
61807 #endif
61808   switch (type) {
61809     case SockType::kStream:
61810       return SOCK_STREAM | kSockCloExec;
61811     case SockType::kDgram:
61812       return SOCK_DGRAM | kSockCloExec;
61813     case SockType::kSeqPacket:
61814       return SOCK_SEQPACKET | kSockCloExec;
61815   }
61816   PERFETTO_CHECK(false);  // For GCC.
61817 }
61818 
MakeSockAddr(SockFamily family,const std::string & socket_name)61819 SockaddrAny MakeSockAddr(SockFamily family, const std::string& socket_name) {
61820   switch (family) {
61821     case SockFamily::kUnix: {
61822       struct sockaddr_un saddr {};
61823       const size_t name_len = socket_name.size();
61824       if (name_len >= sizeof(saddr.sun_path)) {
61825         errno = ENAMETOOLONG;
61826         return SockaddrAny();
61827       }
61828       memcpy(saddr.sun_path, socket_name.data(), name_len);
61829       if (saddr.sun_path[0] == '@') {
61830         saddr.sun_path[0] = '\0';
61831 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
61832         // The MSDN blog claims that abstract (non-filesystem based) AF_UNIX
61833         // socket are supported, but that doesn't seem true.
61834         PERFETTO_ELOG(
61835             "Abstract AF_UNIX sockets are not supported on Windows, see "
61836             "https://github.com/microsoft/WSL/issues/4240");
61837         return SockaddrAny{};
61838 #endif
61839       }
61840       saddr.sun_family = AF_UNIX;
61841       auto size = static_cast<socklen_t>(
61842           __builtin_offsetof(sockaddr_un, sun_path) + name_len + 1);
61843       PERFETTO_CHECK(static_cast<size_t>(size) <= sizeof(saddr));
61844       return SockaddrAny(&saddr, size);
61845     }
61846     case SockFamily::kInet: {
61847       auto parts = SplitString(socket_name, ":");
61848       PERFETTO_CHECK(parts.size() == 2);
61849       struct addrinfo* addr_info = nullptr;
61850       struct addrinfo hints {};
61851       hints.ai_family = AF_INET;
61852       PERFETTO_CHECK(getaddrinfo(parts[0].c_str(), parts[1].c_str(), &hints,
61853                                  &addr_info) == 0);
61854       PERFETTO_CHECK(addr_info->ai_family == AF_INET);
61855       SockaddrAny res(addr_info->ai_addr,
61856                       static_cast<socklen_t>(addr_info->ai_addrlen));
61857       freeaddrinfo(addr_info);
61858       return res;
61859     }
61860     case SockFamily::kInet6: {
61861       auto parts = SplitString(socket_name, "]");
61862       PERFETTO_CHECK(parts.size() == 2);
61863       auto address = SplitString(parts[0], "[");
61864       PERFETTO_CHECK(address.size() == 1);
61865       auto port = SplitString(parts[1], ":");
61866       PERFETTO_CHECK(port.size() == 1);
61867       struct addrinfo* addr_info = nullptr;
61868       struct addrinfo hints {};
61869       hints.ai_family = AF_INET6;
61870       PERFETTO_CHECK(getaddrinfo(address[0].c_str(), port[0].c_str(), &hints,
61871                                  &addr_info) == 0);
61872       PERFETTO_CHECK(addr_info->ai_family == AF_INET6);
61873       SockaddrAny res(addr_info->ai_addr,
61874                       static_cast<socklen_t>(addr_info->ai_addrlen));
61875       freeaddrinfo(addr_info);
61876       return res;
61877     }
61878   }
61879   PERFETTO_CHECK(false);  // For GCC.
61880 }
61881 
CreateSocketHandle(SockFamily family,SockType type)61882 ScopedSocketHandle CreateSocketHandle(SockFamily family, SockType type) {
61883 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
61884   static bool init_winsock_once = [] {
61885     WSADATA ignored{};
61886     return WSAStartup(MAKEWORD(2, 2), &ignored) == 0;
61887   }();
61888   PERFETTO_CHECK(init_winsock_once);
61889 #endif
61890   return ScopedSocketHandle(
61891       socket(GetSockFamily(family), GetSockType(type), 0));
61892 }
61893 
61894 }  // namespace
61895 
61896 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
CloseSocket(SocketHandle s)61897 int CloseSocket(SocketHandle s) {
61898   return ::closesocket(s);
61899 }
61900 #endif
61901 
61902 // +-----------------------+
61903 // | UnixSocketRaw methods |
61904 // +-----------------------+
61905 
61906 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
61907 // static
ShiftMsgHdrPosix(size_t n,struct msghdr * msg)61908 void UnixSocketRaw::ShiftMsgHdrPosix(size_t n, struct msghdr* msg) {
61909   using LenType = decltype(msg->msg_iovlen);  // Mac and Linux don't agree.
61910   for (LenType i = 0; i < msg->msg_iovlen; ++i) {
61911     struct iovec* vec = &msg->msg_iov[i];
61912     if (n < vec->iov_len) {
61913       // We sent a part of this iovec.
61914       vec->iov_base = reinterpret_cast<char*>(vec->iov_base) + n;
61915       vec->iov_len -= n;
61916       msg->msg_iov = vec;
61917       msg->msg_iovlen -= i;
61918       return;
61919     }
61920     // We sent the whole iovec.
61921     n -= vec->iov_len;
61922   }
61923   // We sent all the iovecs.
61924   PERFETTO_CHECK(n == 0);
61925   msg->msg_iovlen = 0;
61926   msg->msg_iov = nullptr;
61927 }
61928 
61929 // static
CreatePairPosix(SockFamily family,SockType type)61930 std::pair<UnixSocketRaw, UnixSocketRaw> UnixSocketRaw::CreatePairPosix(
61931     SockFamily family,
61932     SockType type) {
61933   int fds[2];
61934   if (socketpair(GetSockFamily(family), GetSockType(type), 0, fds) != 0)
61935     return std::make_pair(UnixSocketRaw(), UnixSocketRaw());
61936 
61937   return std::make_pair(UnixSocketRaw(ScopedFile(fds[0]), family, type),
61938                         UnixSocketRaw(ScopedFile(fds[1]), family, type));
61939 }
61940 #endif
61941 
61942 // static
CreateMayFail(SockFamily family,SockType type)61943 UnixSocketRaw UnixSocketRaw::CreateMayFail(SockFamily family, SockType type) {
61944   auto fd = CreateSocketHandle(family, type);
61945   if (!fd)
61946     return UnixSocketRaw();
61947   return UnixSocketRaw(std::move(fd), family, type);
61948 }
61949 
61950 UnixSocketRaw::UnixSocketRaw() = default;
61951 
UnixSocketRaw(SockFamily family,SockType type)61952 UnixSocketRaw::UnixSocketRaw(SockFamily family, SockType type)
61953     : UnixSocketRaw(CreateSocketHandle(family, type), family, type) {}
61954 
UnixSocketRaw(ScopedSocketHandle fd,SockFamily family,SockType type)61955 UnixSocketRaw::UnixSocketRaw(ScopedSocketHandle fd,
61956                              SockFamily family,
61957                              SockType type)
61958     : fd_(std::move(fd)), family_(family), type_(type) {
61959   PERFETTO_CHECK(fd_);
61960 #if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
61961   const int no_sigpipe = 1;
61962   setsockopt(*fd_, SOL_SOCKET, SO_NOSIGPIPE, &no_sigpipe, sizeof(no_sigpipe));
61963 #endif
61964 
61965   if (family == SockFamily::kInet || family == SockFamily::kInet6) {
61966     int flag = 1;
61967     // The reinterpret_cast<const char*> is needed for Windows, where the 4th
61968     // arg is a const char* (on other POSIX system is a const void*).
61969     PERFETTO_CHECK(!setsockopt(*fd_, SOL_SOCKET, SO_REUSEADDR,
61970                                reinterpret_cast<const char*>(&flag),
61971                                sizeof(flag)));
61972     flag = 1;
61973     // Disable Nagle's algorithm, optimize for low-latency.
61974     // See https://github.com/google/perfetto/issues/70.
61975     setsockopt(*fd_, IPPROTO_TCP, TCP_NODELAY,
61976                reinterpret_cast<const char*>(&flag), sizeof(flag));
61977   }
61978 
61979 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
61980   // We use one event handle for all socket events, to stay consistent to what
61981   // we do on UNIX with the base::TaskRunner's poll().
61982   event_handle_.reset(WSACreateEvent());
61983   PERFETTO_CHECK(event_handle_);
61984 #else
61985   // There is no reason why a socket should outlive the process in case of
61986   // exec() by default, this is just working around a broken unix design.
61987   int fcntl_res = fcntl(*fd_, F_SETFD, FD_CLOEXEC);
61988   PERFETTO_CHECK(fcntl_res == 0);
61989 #endif
61990 }
61991 
SetBlocking(bool is_blocking)61992 void UnixSocketRaw::SetBlocking(bool is_blocking) {
61993   PERFETTO_DCHECK(fd_);
61994 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
61995   unsigned long flag = is_blocking ? 0 : 1;  // FIONBIO has reverse logic.
61996   if (is_blocking) {
61997     // When switching between non-blocking -> blocking mode, we need to reset
61998     // the event handle registration, otherwise the call will fail.
61999     PERFETTO_CHECK(WSAEventSelect(*fd_, *event_handle_, 0) == 0);
62000   }
62001   PERFETTO_CHECK(ioctlsocket(*fd_, static_cast<long>(FIONBIO), &flag) == 0);
62002   if (!is_blocking) {
62003     PERFETTO_CHECK(
62004         WSAEventSelect(*fd_, *event_handle_,
62005                        FD_ACCEPT | FD_CONNECT | FD_READ | FD_CLOSE) == 0);
62006   }
62007 #else
62008   int flags = fcntl(*fd_, F_GETFL, 0);
62009   if (!is_blocking) {
62010     flags |= O_NONBLOCK;
62011   } else {
62012     flags &= ~static_cast<int>(O_NONBLOCK);
62013   }
62014   int fcntl_res = fcntl(*fd_, F_SETFL, flags);
62015   PERFETTO_CHECK(fcntl_res == 0);
62016 #endif
62017 }
62018 
RetainOnExec()62019 void UnixSocketRaw::RetainOnExec() {
62020 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
62021   PERFETTO_DCHECK(fd_);
62022   int flags = fcntl(*fd_, F_GETFD, 0);
62023   flags &= ~static_cast<int>(FD_CLOEXEC);
62024   int fcntl_res = fcntl(*fd_, F_SETFD, flags);
62025   PERFETTO_CHECK(fcntl_res == 0);
62026 #endif
62027 }
62028 
DcheckIsBlocking(bool expected) const62029 void UnixSocketRaw::DcheckIsBlocking(bool expected) const {
62030 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
62031   ignore_result(expected);
62032 #else
62033   PERFETTO_DCHECK(fd_);
62034   bool is_blocking = (fcntl(*fd_, F_GETFL, 0) & O_NONBLOCK) == 0;
62035   PERFETTO_DCHECK(is_blocking == expected);
62036 #endif
62037 }
62038 
Bind(const std::string & socket_name)62039 bool UnixSocketRaw::Bind(const std::string& socket_name) {
62040   PERFETTO_DCHECK(fd_);
62041   SockaddrAny addr = MakeSockAddr(family_, socket_name);
62042   if (addr.size == 0)
62043     return false;
62044 
62045   if (bind(*fd_, addr.addr(), addr.size)) {
62046     PERFETTO_DPLOG("bind(%s)", socket_name.c_str());
62047     return false;
62048   }
62049 
62050   return true;
62051 }
62052 
Listen()62053 bool UnixSocketRaw::Listen() {
62054   PERFETTO_DCHECK(fd_);
62055   PERFETTO_DCHECK(type_ == SockType::kStream || type_ == SockType::kSeqPacket);
62056   return listen(*fd_, SOMAXCONN) == 0;
62057 }
62058 
Connect(const std::string & socket_name)62059 bool UnixSocketRaw::Connect(const std::string& socket_name) {
62060   PERFETTO_DCHECK(fd_);
62061   SockaddrAny addr = MakeSockAddr(family_, socket_name);
62062   if (addr.size == 0)
62063     return false;
62064 
62065   int res = PERFETTO_EINTR(connect(*fd_, addr.addr(), addr.size));
62066 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
62067   bool continue_async = WSAGetLastError() == WSAEWOULDBLOCK;
62068 #else
62069   bool continue_async = errno == EINPROGRESS;
62070 #endif
62071   if (res && !continue_async)
62072     return false;
62073 
62074   return true;
62075 }
62076 
Shutdown()62077 void UnixSocketRaw::Shutdown() {
62078 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
62079   // Somebody felt very strongly about the naming of this constant.
62080   shutdown(*fd_, SD_BOTH);
62081 #else
62082   shutdown(*fd_, SHUT_RDWR);
62083 #endif
62084   fd_.reset();
62085 }
62086 
62087 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
62088 
Send(const void * msg,size_t len,const int *,size_t num_fds)62089 ssize_t UnixSocketRaw::Send(const void* msg,
62090                             size_t len,
62091                             const int* /*send_fds*/,
62092                             size_t num_fds) {
62093   PERFETTO_DCHECK(num_fds == 0);
62094   return sendto(*fd_, static_cast<const char*>(msg), static_cast<int>(len), 0,
62095                 nullptr, 0);
62096 }
62097 
Receive(void * msg,size_t len,ScopedFile *,size_t)62098 ssize_t UnixSocketRaw::Receive(void* msg,
62099                                size_t len,
62100                                ScopedFile* /*fd_vec*/,
62101                                size_t /*max_files*/) {
62102   return recv(*fd_, static_cast<char*>(msg), static_cast<int>(len), 0);
62103 }
62104 
62105 #else
62106 // For the interested reader, Linux kernel dive to verify this is not only a
62107 // theoretical possibility: sock_stream_sendmsg, if sock_alloc_send_pskb returns
62108 // NULL [1] (which it does when it gets interrupted [2]), returns early with the
62109 // amount of bytes already sent.
62110 //
62111 // [1]:
62112 // https://elixir.bootlin.com/linux/v4.18.10/source/net/unix/af_unix.c#L1872
62113 // [2]: https://elixir.bootlin.com/linux/v4.18.10/source/net/core/sock.c#L2101
SendMsgAllPosix(struct msghdr * msg)62114 ssize_t UnixSocketRaw::SendMsgAllPosix(struct msghdr* msg) {
62115   // This does not make sense on non-blocking sockets.
62116   PERFETTO_DCHECK(fd_);
62117 
62118   ssize_t total_sent = 0;
62119   while (msg->msg_iov) {
62120     ssize_t sent = PERFETTO_EINTR(sendmsg(*fd_, msg, kNoSigPipe));
62121     if (sent <= 0) {
62122       if (sent == -1 && IsAgain(errno))
62123         return total_sent;
62124       return sent;
62125     }
62126     total_sent += sent;
62127     ShiftMsgHdrPosix(static_cast<size_t>(sent), msg);
62128     // Only send the ancillary data with the first sendmsg call.
62129     msg->msg_control = nullptr;
62130     msg->msg_controllen = 0;
62131   }
62132   return total_sent;
62133 }
62134 
Send(const void * msg,size_t len,const int * send_fds,size_t num_fds)62135 ssize_t UnixSocketRaw::Send(const void* msg,
62136                             size_t len,
62137                             const int* send_fds,
62138                             size_t num_fds) {
62139   PERFETTO_DCHECK(fd_);
62140   msghdr msg_hdr = {};
62141   iovec iov = {const_cast<void*>(msg), len};
62142   msg_hdr.msg_iov = &iov;
62143   msg_hdr.msg_iovlen = 1;
62144   alignas(cmsghdr) char control_buf[256];
62145 
62146   if (num_fds > 0) {
62147     const auto raw_ctl_data_sz = num_fds * sizeof(int);
62148     const CBufLenType control_buf_len =
62149         static_cast<CBufLenType>(CMSG_SPACE(raw_ctl_data_sz));
62150     PERFETTO_CHECK(control_buf_len <= sizeof(control_buf));
62151     memset(control_buf, 0, sizeof(control_buf));
62152     msg_hdr.msg_control = control_buf;
62153     msg_hdr.msg_controllen = control_buf_len;  // used by CMSG_FIRSTHDR
62154     struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg_hdr);
62155     cmsg->cmsg_level = SOL_SOCKET;
62156     cmsg->cmsg_type = SCM_RIGHTS;
62157     cmsg->cmsg_len = static_cast<CBufLenType>(CMSG_LEN(raw_ctl_data_sz));
62158     memcpy(CMSG_DATA(cmsg), send_fds, num_fds * sizeof(int));
62159     // note: if we were to send multiple cmsghdr structures, then
62160     // msg_hdr.msg_controllen would need to be adjusted, see "man 3 cmsg".
62161   }
62162 
62163   return SendMsgAllPosix(&msg_hdr);
62164 }
62165 
Receive(void * msg,size_t len,ScopedFile * fd_vec,size_t max_files)62166 ssize_t UnixSocketRaw::Receive(void* msg,
62167                                size_t len,
62168                                ScopedFile* fd_vec,
62169                                size_t max_files) {
62170   PERFETTO_DCHECK(fd_);
62171   msghdr msg_hdr = {};
62172   iovec iov = {msg, len};
62173   msg_hdr.msg_iov = &iov;
62174   msg_hdr.msg_iovlen = 1;
62175   alignas(cmsghdr) char control_buf[256];
62176 
62177   if (max_files > 0) {
62178     msg_hdr.msg_control = control_buf;
62179     msg_hdr.msg_controllen =
62180         static_cast<CBufLenType>(CMSG_SPACE(max_files * sizeof(int)));
62181     PERFETTO_CHECK(msg_hdr.msg_controllen <= sizeof(control_buf));
62182   }
62183   const ssize_t sz = PERFETTO_EINTR(recvmsg(*fd_, &msg_hdr, 0));
62184   if (sz <= 0) {
62185     return sz;
62186   }
62187   PERFETTO_CHECK(static_cast<size_t>(sz) <= len);
62188 
62189   int* fds = nullptr;
62190   uint32_t fds_len = 0;
62191 
62192   if (max_files > 0) {
62193     for (cmsghdr* cmsg = CMSG_FIRSTHDR(&msg_hdr); cmsg;
62194          cmsg = CMSG_NXTHDR(&msg_hdr, cmsg)) {
62195       const size_t payload_len = cmsg->cmsg_len - CMSG_LEN(0);
62196       if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
62197         PERFETTO_DCHECK(payload_len % sizeof(int) == 0u);
62198         PERFETTO_CHECK(fds == nullptr);
62199         fds = reinterpret_cast<int*>(CMSG_DATA(cmsg));
62200         fds_len = static_cast<uint32_t>(payload_len / sizeof(int));
62201       }
62202     }
62203   }
62204 
62205   if (msg_hdr.msg_flags & MSG_TRUNC || msg_hdr.msg_flags & MSG_CTRUNC) {
62206     for (size_t i = 0; fds && i < fds_len; ++i)
62207       close(fds[i]);
62208     PERFETTO_ELOG(
62209         "Socket message truncated. This might be due to a SELinux denial on "
62210         "fd:use.");
62211     errno = EMSGSIZE;
62212     return -1;
62213   }
62214 
62215   for (size_t i = 0; fds && i < fds_len; ++i) {
62216     if (i < max_files)
62217       fd_vec[i].reset(fds[i]);
62218     else
62219       close(fds[i]);
62220   }
62221 
62222   return sz;
62223 }
62224 #endif  // OS_WIN
62225 
SetTxTimeout(uint32_t timeout_ms)62226 bool UnixSocketRaw::SetTxTimeout(uint32_t timeout_ms) {
62227   PERFETTO_DCHECK(fd_);
62228 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
62229   DWORD timeout = timeout_ms;
62230 #else
62231   struct timeval timeout {};
62232   uint32_t timeout_sec = timeout_ms / 1000;
62233   timeout.tv_sec = static_cast<decltype(timeout.tv_sec)>(timeout_sec);
62234   timeout.tv_usec = static_cast<decltype(timeout.tv_usec)>(
62235       (timeout_ms - (timeout_sec * 1000)) * 1000);
62236 #endif
62237   return setsockopt(*fd_, SOL_SOCKET, SO_SNDTIMEO,
62238                     reinterpret_cast<const char*>(&timeout),
62239                     sizeof(timeout)) == 0;
62240 }
62241 
SetRxTimeout(uint32_t timeout_ms)62242 bool UnixSocketRaw::SetRxTimeout(uint32_t timeout_ms) {
62243   PERFETTO_DCHECK(fd_);
62244 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
62245   DWORD timeout = timeout_ms;
62246 #else
62247   struct timeval timeout {};
62248   uint32_t timeout_sec = timeout_ms / 1000;
62249   timeout.tv_sec = static_cast<decltype(timeout.tv_sec)>(timeout_sec);
62250   timeout.tv_usec = static_cast<decltype(timeout.tv_usec)>(
62251       (timeout_ms - (timeout_sec * 1000)) * 1000);
62252 #endif
62253   return setsockopt(*fd_, SOL_SOCKET, SO_RCVTIMEO,
62254                     reinterpret_cast<const char*>(&timeout),
62255                     sizeof(timeout)) == 0;
62256 }
62257 
62258 #if defined(__GNUC__) && !PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
62259 #pragma GCC diagnostic pop
62260 #endif
62261 
62262 // +--------------------+
62263 // | UnixSocket methods |
62264 // +--------------------+
62265 
62266 // TODO(primiano): Add ThreadChecker to methods of this class.
62267 
62268 // static
Listen(const std::string & socket_name,EventListener * event_listener,TaskRunner * task_runner,SockFamily sock_family,SockType sock_type)62269 std::unique_ptr<UnixSocket> UnixSocket::Listen(const std::string& socket_name,
62270                                                EventListener* event_listener,
62271                                                TaskRunner* task_runner,
62272                                                SockFamily sock_family,
62273                                                SockType sock_type) {
62274   auto sock_raw = UnixSocketRaw::CreateMayFail(sock_family, sock_type);
62275   if (!sock_raw || !sock_raw.Bind(socket_name))
62276     return nullptr;
62277 
62278   // Forward the call to the Listen() overload below.
62279   return Listen(sock_raw.ReleaseFd(), event_listener, task_runner, sock_family,
62280                 sock_type);
62281 }
62282 
62283 // static
Listen(ScopedSocketHandle fd,EventListener * event_listener,TaskRunner * task_runner,SockFamily sock_family,SockType sock_type)62284 std::unique_ptr<UnixSocket> UnixSocket::Listen(ScopedSocketHandle fd,
62285                                                EventListener* event_listener,
62286                                                TaskRunner* task_runner,
62287                                                SockFamily sock_family,
62288                                                SockType sock_type) {
62289   return std::unique_ptr<UnixSocket>(new UnixSocket(
62290       event_listener, task_runner, std::move(fd), State::kListening,
62291       sock_family, sock_type, SockPeerCredMode::kDefault));
62292 }
62293 
62294 // static
Connect(const std::string & socket_name,EventListener * event_listener,TaskRunner * task_runner,SockFamily sock_family,SockType sock_type,SockPeerCredMode peer_cred_mode)62295 std::unique_ptr<UnixSocket> UnixSocket::Connect(
62296     const std::string& socket_name,
62297     EventListener* event_listener,
62298     TaskRunner* task_runner,
62299     SockFamily sock_family,
62300     SockType sock_type,
62301     SockPeerCredMode peer_cred_mode) {
62302   std::unique_ptr<UnixSocket> sock(new UnixSocket(
62303       event_listener, task_runner, sock_family, sock_type, peer_cred_mode));
62304   sock->DoConnect(socket_name);
62305   return sock;
62306 }
62307 
62308 // static
AdoptConnected(ScopedSocketHandle fd,EventListener * event_listener,TaskRunner * task_runner,SockFamily sock_family,SockType sock_type,SockPeerCredMode peer_cred_mode)62309 std::unique_ptr<UnixSocket> UnixSocket::AdoptConnected(
62310     ScopedSocketHandle fd,
62311     EventListener* event_listener,
62312     TaskRunner* task_runner,
62313     SockFamily sock_family,
62314     SockType sock_type,
62315     SockPeerCredMode peer_cred_mode) {
62316   return std::unique_ptr<UnixSocket>(new UnixSocket(
62317       event_listener, task_runner, std::move(fd), State::kConnected,
62318       sock_family, sock_type, peer_cred_mode));
62319 }
62320 
UnixSocket(EventListener * event_listener,TaskRunner * task_runner,SockFamily sock_family,SockType sock_type,SockPeerCredMode peer_cred_mode)62321 UnixSocket::UnixSocket(EventListener* event_listener,
62322                        TaskRunner* task_runner,
62323                        SockFamily sock_family,
62324                        SockType sock_type,
62325                        SockPeerCredMode peer_cred_mode)
62326     : UnixSocket(event_listener,
62327                  task_runner,
62328                  ScopedSocketHandle(),
62329                  State::kDisconnected,
62330                  sock_family,
62331                  sock_type,
62332                  peer_cred_mode) {}
62333 
UnixSocket(EventListener * event_listener,TaskRunner * task_runner,ScopedSocketHandle adopt_fd,State adopt_state,SockFamily sock_family,SockType sock_type,SockPeerCredMode peer_cred_mode)62334 UnixSocket::UnixSocket(EventListener* event_listener,
62335                        TaskRunner* task_runner,
62336                        ScopedSocketHandle adopt_fd,
62337                        State adopt_state,
62338                        SockFamily sock_family,
62339                        SockType sock_type,
62340                        SockPeerCredMode peer_cred_mode)
62341     : peer_cred_mode_(peer_cred_mode),
62342       event_listener_(event_listener),
62343       task_runner_(task_runner),
62344       weak_ptr_factory_(this) {
62345   state_ = State::kDisconnected;
62346   if (adopt_state == State::kDisconnected) {
62347     PERFETTO_DCHECK(!adopt_fd);
62348     sock_raw_ = UnixSocketRaw::CreateMayFail(sock_family, sock_type);
62349     if (!sock_raw_)
62350       return;
62351   } else if (adopt_state == State::kConnected) {
62352     PERFETTO_DCHECK(adopt_fd);
62353     sock_raw_ = UnixSocketRaw(std::move(adopt_fd), sock_family, sock_type);
62354     state_ = State::kConnected;
62355 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
62356     if (peer_cred_mode_ == SockPeerCredMode::kReadOnConnect)
62357       ReadPeerCredentialsPosix();
62358 #endif
62359   } else if (adopt_state == State::kListening) {
62360     // We get here from Listen().
62361 
62362     // |adopt_fd| might genuinely be invalid if the bind() failed.
62363     if (!adopt_fd)
62364       return;
62365 
62366     sock_raw_ = UnixSocketRaw(std::move(adopt_fd), sock_family, sock_type);
62367     if (!sock_raw_.Listen()) {
62368       PERFETTO_DPLOG("listen() failed");
62369       return;
62370     }
62371     state_ = State::kListening;
62372   } else {
62373     PERFETTO_FATAL("Unexpected adopt_state");  // Unfeasible.
62374   }
62375 
62376   PERFETTO_CHECK(sock_raw_);
62377 
62378   sock_raw_.SetBlocking(false);
62379 
62380   WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
62381 
62382   task_runner_->AddFileDescriptorWatch(sock_raw_.watch_handle(), [weak_ptr] {
62383     if (weak_ptr)
62384       weak_ptr->OnEvent();
62385   });
62386 }
62387 
~UnixSocket()62388 UnixSocket::~UnixSocket() {
62389   // The implicit dtor of |weak_ptr_factory_| will no-op pending callbacks.
62390   Shutdown(true);
62391 }
62392 
ReleaseSocket()62393 UnixSocketRaw UnixSocket::ReleaseSocket() {
62394   // This will invalidate any pending calls to OnEvent.
62395   state_ = State::kDisconnected;
62396   if (sock_raw_)
62397     task_runner_->RemoveFileDescriptorWatch(sock_raw_.watch_handle());
62398 
62399   return std::move(sock_raw_);
62400 }
62401 
62402 // Called only by the Connect() static constructor.
DoConnect(const std::string & socket_name)62403 void UnixSocket::DoConnect(const std::string& socket_name) {
62404   PERFETTO_DCHECK(state_ == State::kDisconnected);
62405 
62406   // This is the only thing that can gracefully fail in the ctor.
62407   if (!sock_raw_)
62408     return NotifyConnectionState(false);
62409 
62410   if (!sock_raw_.Connect(socket_name))
62411     return NotifyConnectionState(false);
62412 
62413   // At this point either connect() succeeded or started asynchronously
62414   // (errno = EINPROGRESS).
62415   state_ = State::kConnecting;
62416 
62417   // Even if the socket is non-blocking, connecting to a UNIX socket can be
62418   // acknowledged straight away rather than returning EINPROGRESS.
62419   // The decision here is to deal with the two cases uniformly, at the cost of
62420   // delaying the straight-away-connect() case by one task, to avoid depending
62421   // on implementation details of UNIX socket on the various OSes.
62422   // Posting the OnEvent() below emulates a wakeup of the FD watch. OnEvent(),
62423   // which knows how to deal with spurious wakeups, will poll the SO_ERROR and
62424   // evolve, if necessary, the state into either kConnected or kDisconnected.
62425   WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
62426   task_runner_->PostTask([weak_ptr] {
62427     if (weak_ptr)
62428       weak_ptr->OnEvent();
62429   });
62430 }
62431 
62432 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
ReadPeerCredentialsPosix()62433 void UnixSocket::ReadPeerCredentialsPosix() {
62434   // Peer credentials are supported only on AF_UNIX sockets.
62435   if (sock_raw_.family() != SockFamily::kUnix)
62436     return;
62437   PERFETTO_CHECK(peer_cred_mode_ != SockPeerCredMode::kIgnore);
62438 
62439 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
62440     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
62441   struct ucred user_cred;
62442   socklen_t len = sizeof(user_cred);
62443   int fd = sock_raw_.fd();
62444   int res = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &user_cred, &len);
62445   PERFETTO_CHECK(res == 0);
62446   peer_uid_ = user_cred.uid;
62447   peer_pid_ = user_cred.pid;
62448 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
62449   struct xucred user_cred;
62450   socklen_t len = sizeof(user_cred);
62451   int res = getsockopt(sock_raw_.fd(), 0, LOCAL_PEERCRED, &user_cred, &len);
62452   PERFETTO_CHECK(res == 0 && user_cred.cr_version == XUCRED_VERSION);
62453   peer_uid_ = static_cast<uid_t>(user_cred.cr_uid);
62454   // There is no pid in the LOCAL_PEERCREDS for MacOS / FreeBSD.
62455 #endif
62456 }
62457 #endif  // !OS_WIN
62458 
62459 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
OnEvent()62460 void UnixSocket::OnEvent() {
62461   WSANETWORKEVENTS evts{};
62462   PERFETTO_CHECK(WSAEnumNetworkEvents(sock_raw_.fd(), sock_raw_.watch_handle(),
62463                                       &evts) == 0);
62464   if (state_ == State::kDisconnected)
62465     return;  // Some spurious event, typically queued just before Shutdown().
62466 
62467   if (state_ == State::kConnecting && (evts.lNetworkEvents & FD_CONNECT)) {
62468     PERFETTO_DCHECK(sock_raw_);
62469     int err = evts.iErrorCode[FD_CONNECT_BIT];
62470     if (err) {
62471       PERFETTO_DPLOG("Connection error: %d", err);
62472       Shutdown(false);
62473       event_listener_->OnConnect(this, false /* connected */);
62474       return;
62475     }
62476 
62477     // kReadOnConnect is not supported on Windows.
62478     PERFETTO_DCHECK(peer_cred_mode_ != SockPeerCredMode::kReadOnConnect);
62479     state_ = State::kConnected;
62480     event_listener_->OnConnect(this, true /* connected */);
62481   }
62482 
62483   // This is deliberately NOT an else-if. When a client socket connects and
62484   // there is already data queued, the following will happen within the same
62485   // OnEvent() call:
62486   // 1. The block above will transition kConnecting -> kConnected.
62487   // 2. This block will cause an OnDataAvailable() call.
62488   // Unlike UNIX, where poll() keeps signalling the event until the client
62489   // does a recv(), Windows is more picky and stops signalling the event until
62490   // the next call to recv() is made. In other words, in Windows we cannot
62491   // miss an OnDataAvailable() call or the event pump will stop.
62492   if (state_ == State::kConnected) {
62493     if (evts.lNetworkEvents & FD_READ) {
62494       event_listener_->OnDataAvailable(this);
62495       // TODO(primiano): I am very conflicted here. Because of the behavior
62496       // described above, if the event listener doesn't do a Recv() call in
62497       // the OnDataAvailable() callback, WinSock won't notify the event ever
62498       // again. On one side, I don't see any reason why a client should decide
62499       // to not do a Recv() in OnDataAvailable. On the other side, the
62500       // behavior here diverges from UNIX, where OnDataAvailable() would be
62501       // re-posted immediately. In both cases, not doing a Recv() in
62502       // OnDataAvailable, leads to something bad (getting stuck on Windows,
62503       // getting in a hot loop on Linux), so doesn't feel we should worry too
62504       // much about this. If we wanted to keep the behavrior consistent, here
62505       // we should do something like: `if (sock_raw_)
62506       // sock_raw_.SetBlocking(false)` (Note that the socket might be closed
62507       // by the time we come back here, hence the if part).
62508       return;
62509     }
62510     // Could read EOF and disconnect here.
62511     if (evts.lNetworkEvents & FD_CLOSE) {
62512       Shutdown(true);
62513       return;
62514     }
62515   }
62516 
62517   // New incoming connection.
62518   if (state_ == State::kListening && (evts.lNetworkEvents & FD_ACCEPT)) {
62519     // There could be more than one incoming connection behind each FD watch
62520     // notification. Drain'em all.
62521     for (;;) {
62522       // Note: right now we don't need the remote endpoint, hence we pass
62523       // nullptr to |addr| and |addrlen|. If we ever need to do so, be
62524       // extremely careful. Windows' WinSock API will happily write more than
62525       // |addrlen| (hence corrupt the stack) if the |addr| argument passed is
62526       // not big enough (e.g. passing a struct sockaddr_in to a AF_UNIX
62527       // socket, where sizeof(sockaddr_un) is >> sizef(sockaddr_in)). It seems
62528       // a Windows / CRT bug in the AF_UNIX implementation.
62529       ScopedSocketHandle new_fd(accept(sock_raw_.fd(), nullptr, nullptr));
62530       if (!new_fd)
62531         return;
62532       std::unique_ptr<UnixSocket> new_sock(new UnixSocket(
62533           event_listener_, task_runner_, std::move(new_fd), State::kConnected,
62534           sock_raw_.family(), sock_raw_.type(), peer_cred_mode_));
62535       event_listener_->OnNewIncomingConnection(this, std::move(new_sock));
62536     }
62537   }
62538 }
62539 #else
OnEvent()62540 void UnixSocket::OnEvent() {
62541   if (state_ == State::kDisconnected)
62542     return;  // Some spurious event, typically queued just before Shutdown().
62543 
62544   if (state_ == State::kConnected)
62545     return event_listener_->OnDataAvailable(this);
62546 
62547   if (state_ == State::kConnecting) {
62548     PERFETTO_DCHECK(sock_raw_);
62549     int sock_err = EINVAL;
62550     socklen_t err_len = sizeof(sock_err);
62551     int res =
62552         getsockopt(sock_raw_.fd(), SOL_SOCKET, SO_ERROR, &sock_err, &err_len);
62553 
62554     if (res == 0 && sock_err == EINPROGRESS)
62555       return;  // Not connected yet, just a spurious FD watch wakeup.
62556     if (res == 0 && sock_err == 0) {
62557       if (peer_cred_mode_ == SockPeerCredMode::kReadOnConnect)
62558         ReadPeerCredentialsPosix();
62559       state_ = State::kConnected;
62560       return event_listener_->OnConnect(this, true /* connected */);
62561     }
62562     PERFETTO_DLOG("Connection error: %s", strerror(sock_err));
62563     Shutdown(false);
62564     return event_listener_->OnConnect(this, false /* connected */);
62565   }
62566 
62567   // New incoming connection.
62568   if (state_ == State::kListening) {
62569     // There could be more than one incoming connection behind each FD watch
62570     // notification. Drain'em all.
62571     for (;;) {
62572       ScopedFile new_fd(
62573           PERFETTO_EINTR(accept(sock_raw_.fd(), nullptr, nullptr)));
62574       if (!new_fd)
62575         return;
62576       std::unique_ptr<UnixSocket> new_sock(new UnixSocket(
62577           event_listener_, task_runner_, std::move(new_fd), State::kConnected,
62578           sock_raw_.family(), sock_raw_.type(), peer_cred_mode_));
62579       event_listener_->OnNewIncomingConnection(this, std::move(new_sock));
62580     }
62581   }
62582 }
62583 #endif
62584 
Send(const void * msg,size_t len,const int * send_fds,size_t num_fds)62585 bool UnixSocket::Send(const void* msg,
62586                       size_t len,
62587                       const int* send_fds,
62588                       size_t num_fds) {
62589   if (state_ != State::kConnected) {
62590     errno = ENOTCONN;
62591     return false;
62592   }
62593 
62594   sock_raw_.SetBlocking(true);
62595   const ssize_t sz = sock_raw_.Send(msg, len, send_fds, num_fds);
62596   sock_raw_.SetBlocking(false);
62597 
62598   if (sz == static_cast<ssize_t>(len)) {
62599     return true;
62600   }
62601 
62602   // If we ever decide to support non-blocking sends again, here we should
62603   // watch for both EAGAIN and EWOULDBLOCK (see base::IsAgain()).
62604 
62605   // If sendmsg() succeeds but the returned size is >= 0 and < |len| it means
62606   // that the endpoint disconnected in the middle of the read, and we managed
62607   // to send only a portion of the buffer.
62608   // If sz < 0, either the other endpoint disconnected (ECONNRESET) or some
62609   // other error happened. In both cases we should just give up.
62610   PERFETTO_DPLOG("sendmsg() failed");
62611   Shutdown(true);
62612   return false;
62613 }
62614 
Shutdown(bool notify)62615 void UnixSocket::Shutdown(bool notify) {
62616   WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
62617   if (notify) {
62618     if (state_ == State::kConnected) {
62619       task_runner_->PostTask([weak_ptr] {
62620         if (weak_ptr)
62621           weak_ptr->event_listener_->OnDisconnect(weak_ptr.get());
62622       });
62623     } else if (state_ == State::kConnecting) {
62624       task_runner_->PostTask([weak_ptr] {
62625         if (weak_ptr)
62626           weak_ptr->event_listener_->OnConnect(weak_ptr.get(), false);
62627       });
62628     }
62629   }
62630 
62631   if (sock_raw_) {
62632     task_runner_->RemoveFileDescriptorWatch(sock_raw_.watch_handle());
62633     sock_raw_.Shutdown();
62634   }
62635   state_ = State::kDisconnected;
62636 }
62637 
Receive(void * msg,size_t len,ScopedFile * fd_vec,size_t max_files)62638 size_t UnixSocket::Receive(void* msg,
62639                            size_t len,
62640                            ScopedFile* fd_vec,
62641                            size_t max_files) {
62642   if (state_ != State::kConnected)
62643     return 0;
62644 
62645   const ssize_t sz = sock_raw_.Receive(msg, len, fd_vec, max_files);
62646 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
62647   bool async_would_block = WSAGetLastError() == WSAEWOULDBLOCK;
62648 #else
62649   bool async_would_block = IsAgain(errno);
62650 #endif
62651   if (sz < 0 && async_would_block)
62652     return 0;
62653 
62654   if (sz <= 0) {
62655     Shutdown(true);
62656     return 0;
62657   }
62658   PERFETTO_CHECK(static_cast<size_t>(sz) <= len);
62659   return static_cast<size_t>(sz);
62660 }
62661 
ReceiveString(size_t max_length)62662 std::string UnixSocket::ReceiveString(size_t max_length) {
62663   std::unique_ptr<char[]> buf(new char[max_length + 1]);
62664   size_t rsize = Receive(buf.get(), max_length);
62665   PERFETTO_CHECK(rsize <= max_length);
62666   buf[rsize] = '\0';
62667   return std::string(buf.get());
62668 }
62669 
NotifyConnectionState(bool success)62670 void UnixSocket::NotifyConnectionState(bool success) {
62671   if (!success)
62672     Shutdown(false);
62673 
62674   WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
62675   task_runner_->PostTask([weak_ptr, success] {
62676     if (weak_ptr)
62677       weak_ptr->event_listener_->OnConnect(weak_ptr.get(), success);
62678   });
62679 }
62680 
~EventListener()62681 UnixSocket::EventListener::~EventListener() {}
OnNewIncomingConnection(UnixSocket *,std::unique_ptr<UnixSocket>)62682 void UnixSocket::EventListener::OnNewIncomingConnection(
62683     UnixSocket*,
62684     std::unique_ptr<UnixSocket>) {}
OnConnect(UnixSocket *,bool)62685 void UnixSocket::EventListener::OnConnect(UnixSocket*, bool) {}
OnDisconnect(UnixSocket *)62686 void UnixSocket::EventListener::OnDisconnect(UnixSocket*) {}
OnDataAvailable(UnixSocket *)62687 void UnixSocket::EventListener::OnDataAvailable(UnixSocket*) {}
62688 
62689 }  // namespace base
62690 }  // namespace perfetto
62691 // gen_amalgamated begin source: src/ipc/buffered_frame_deserializer.cc
62692 // gen_amalgamated begin header: src/ipc/buffered_frame_deserializer.h
62693 // gen_amalgamated begin header: include/perfetto/ext/ipc/basic_types.h
62694 /*
62695  * Copyright (C) 2017 The Android Open Source Project
62696  *
62697  * Licensed under the Apache License, Version 2.0 (the "License");
62698  * you may not use this file except in compliance with the License.
62699  * You may obtain a copy of the License at
62700  *
62701  *      http://www.apache.org/licenses/LICENSE-2.0
62702  *
62703  * Unless required by applicable law or agreed to in writing, software
62704  * distributed under the License is distributed on an "AS IS" BASIS,
62705  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
62706  * See the License for the specific language governing permissions and
62707  * limitations under the License.
62708  */
62709 
62710 #ifndef INCLUDE_PERFETTO_EXT_IPC_BASIC_TYPES_H_
62711 #define INCLUDE_PERFETTO_EXT_IPC_BASIC_TYPES_H_
62712 
62713 #include <stddef.h>
62714 #include <stdint.h>
62715 #include <sys/types.h>
62716 
62717 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
62718 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
62719 
62720 namespace perfetto {
62721 namespace ipc {
62722 
62723 using ProtoMessage = ::protozero::CppMessageObj;
62724 using ServiceID = uint32_t;
62725 using MethodID = uint32_t;
62726 using ClientID = uint64_t;
62727 using RequestID = uint64_t;
62728 
62729 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
62730 // AF_UNIX on Windows is supported only on Windows 10 from build 17063.
62731 // Also it doesn't bring major advantages compared to a TCP socket.
62732 // See go/perfetto-win .
62733 constexpr bool kUseTCPSocket = true;
62734 #else
62735 // On Android, Linux, Mac use a AF_UNIX socket.
62736 constexpr bool kUseTCPSocket = false;
62737 #endif
62738 
62739 // This determines the maximum size allowed for an IPC message. Trying to send
62740 // or receive a larger message will hit DCHECK(s) and auto-disconnect.
62741 constexpr size_t kIPCBufferSize = 128 * 1024;
62742 
62743 constexpr uid_t kInvalidUid = static_cast<uid_t>(-1);
62744 
62745 }  // namespace ipc
62746 }  // namespace perfetto
62747 
62748 #endif  // INCLUDE_PERFETTO_EXT_IPC_BASIC_TYPES_H_
62749 /*
62750  * Copyright (C) 2017 The Android Open Source Project
62751  *
62752  * Licensed under the Apache License, Version 2.0 (the "License");
62753  * you may not use this file except in compliance with the License.
62754  * You may obtain a copy of the License at
62755  *
62756  *      http://www.apache.org/licenses/LICENSE-2.0
62757  *
62758  * Unless required by applicable law or agreed to in writing, software
62759  * distributed under the License is distributed on an "AS IS" BASIS,
62760  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
62761  * See the License for the specific language governing permissions and
62762  * limitations under the License.
62763  */
62764 
62765 #ifndef SRC_IPC_BUFFERED_FRAME_DESERIALIZER_H_
62766 #define SRC_IPC_BUFFERED_FRAME_DESERIALIZER_H_
62767 
62768 #include <stddef.h>
62769 
62770 #include <list>
62771 #include <memory>
62772 
62773 // gen_amalgamated expanded: #include "perfetto/ext/base/paged_memory.h"
62774 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
62775 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
62776 
62777 namespace perfetto {
62778 
62779 namespace protos {
62780 namespace gen {
62781 class IPCFrame;
62782 }  // namespace gen
62783 }  // namespace protos
62784 
62785 namespace ipc {
62786 
62787 using Frame = ::perfetto::protos::gen::IPCFrame;
62788 
62789 // Deserializes incoming frames, taking care of buffering and tokenization.
62790 // Used by both host and client to decode incoming frames.
62791 //
62792 // Which problem does it solve?
62793 // ----------------------------
62794 // The wire protocol is as follows:
62795 // [32-bit frame size][proto-encoded Frame], e.g:
62796 // [06 00 00 00][00 11 22 33 44 55 66]
62797 // [02 00 00 00][AA BB]
62798 // [04 00 00 00][CC DD EE FF]
62799 // However, given that the socket works in SOCK_STREAM mode, the recv() calls
62800 // might see the following:
62801 // 06 00 00
62802 // 00 00 11 22 33 44 55
62803 // 66 02 00 00 00 ...
62804 // This class takes care of buffering efficiently the data received, without
62805 // making any assumption on how the incoming data will be chunked by the socket.
62806 // For instance, it is possible that a recv() doesn't produce any frame (because
62807 // it received only a part of the frame) or produces more than one frame.
62808 //
62809 // Usage
62810 // -----
62811 // Both host and client use this as follows:
62812 //
62813 // auto buf = rpc_frame_decoder.BeginReceive();
62814 // size_t rsize = socket.recv(buf.first, buf.second);
62815 // rpc_frame_decoder.EndReceive(rsize);
62816 // while (Frame frame = rpc_frame_decoder.PopNextFrame()) {
62817 //   ... process |frame|
62818 // }
62819 //
62820 // Design goals:
62821 // -------------
62822 // - Optimize for the realistic case of each recv() receiving one or more
62823 //   whole frames. In this case no memmove is performed.
62824 // - Guarantee that frames lay in a virtually contiguous memory area.
62825 //   This allows to use the protobuf-lite deserialization API (scattered
62826 //   deserialization is supported only by libprotobuf-full).
62827 // - Put a hard boundary to the size of the incoming buffer. This is to prevent
62828 //   that a malicious sends an abnormally large frame and OOMs us.
62829 // - Simplicity: just use a linear mmap region. No reallocations or scattering.
62830 //   Takes care of madvise()-ing unused memory.
62831 
62832 class BufferedFrameDeserializer {
62833  public:
62834   struct ReceiveBuffer {
62835     char* data;
62836     size_t size;
62837   };
62838 
62839   // |max_capacity| is overridable only for tests.
62840   explicit BufferedFrameDeserializer(size_t max_capacity = kIPCBufferSize);
62841   ~BufferedFrameDeserializer();
62842 
62843   // This function doesn't really belong here as it does Serialization, unlike
62844   // the rest of this class. However it is so small and has so many dependencies
62845   // in common that doesn't justify having its own class.
62846   static std::string Serialize(const Frame&);
62847 
62848   // Returns a buffer that can be passed to recv(). The buffer is deliberately
62849   // not initialized.
62850   ReceiveBuffer BeginReceive();
62851 
62852   // Must be called soon after BeginReceive().
62853   // |recv_size| is the number of valid bytes that have been written into the
62854   // buffer previously returned by BeginReceive() (the return value of recv()).
62855   // Returns false if a header > |max_capacity| is received, in which case the
62856   // caller is expected to shutdown the socket and terminate the ipc.
62857   bool EndReceive(size_t recv_size) PERFETTO_WARN_UNUSED_RESULT;
62858 
62859   // Decodes and returns the next decoded frame in the buffer if any, nullptr
62860   // if no further frames have been decoded.
62861   std::unique_ptr<Frame> PopNextFrame();
62862 
capacity() const62863   size_t capacity() const { return capacity_; }
size() const62864   size_t size() const { return size_; }
62865 
62866  private:
62867   BufferedFrameDeserializer(const BufferedFrameDeserializer&) = delete;
62868   BufferedFrameDeserializer& operator=(const BufferedFrameDeserializer&) =
62869       delete;
62870 
62871   // If a valid frame is decoded it is added to |decoded_frames_|.
62872   void DecodeFrame(const char*, size_t);
62873 
buf()62874   char* buf() { return reinterpret_cast<char*>(buf_.Get()); }
62875 
62876   base::PagedMemory buf_;
62877   const size_t capacity_ = 0;  // sizeof(|buf_|).
62878 
62879   // THe number of bytes in |buf_| that contain valid data (as a result of
62880   // EndReceive()). This is always <= |capacity_|.
62881   size_t size_ = 0;
62882 
62883   std::list<std::unique_ptr<Frame>> decoded_frames_;
62884 };
62885 
62886 }  // namespace ipc
62887 }  // namespace perfetto
62888 
62889 #endif  // SRC_IPC_BUFFERED_FRAME_DESERIALIZER_H_
62890 /*
62891  * Copyright (C) 2017 The Android Open Source Project
62892  *
62893  * Licensed under the Apache License, Version 2.0 (the "License");
62894  * you may not use this file except in compliance with the License.
62895  * You may obtain a copy of the License at
62896  *
62897  *      http://www.apache.org/licenses/LICENSE-2.0
62898  *
62899  * Unless required by applicable law or agreed to in writing, software
62900  * distributed under the License is distributed on an "AS IS" BASIS,
62901  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
62902  * See the License for the specific language governing permissions and
62903  * limitations under the License.
62904  */
62905 
62906 // gen_amalgamated expanded: #include "src/ipc/buffered_frame_deserializer.h"
62907 
62908 #include <inttypes.h>
62909 
62910 #include <algorithm>
62911 #include <type_traits>
62912 #include <utility>
62913 
62914 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
62915 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
62916 
62917 // gen_amalgamated expanded: #include "protos/perfetto/ipc/wire_protocol.gen.h"
62918 
62919 namespace perfetto {
62920 namespace ipc {
62921 
62922 namespace {
62923 
62924 // The header is just the number of bytes of the Frame protobuf message.
62925 constexpr size_t kHeaderSize = sizeof(uint32_t);
62926 }  // namespace
62927 
BufferedFrameDeserializer(size_t max_capacity)62928 BufferedFrameDeserializer::BufferedFrameDeserializer(size_t max_capacity)
62929     : capacity_(max_capacity) {
62930   PERFETTO_CHECK(max_capacity % base::GetSysPageSize() == 0);
62931   PERFETTO_CHECK(max_capacity >= base::GetSysPageSize());
62932 }
62933 
62934 BufferedFrameDeserializer::~BufferedFrameDeserializer() = default;
62935 
62936 BufferedFrameDeserializer::ReceiveBuffer
BeginReceive()62937 BufferedFrameDeserializer::BeginReceive() {
62938   // Upon the first recv initialize the buffer to the max message size but
62939   // release the physical memory for all but the first page. The kernel will
62940   // automatically give us physical pages back as soon as we page-fault on them.
62941   if (!buf_.IsValid()) {
62942     PERFETTO_DCHECK(size_ == 0);
62943     // TODO(eseckler): Don't commit all of the buffer at once on Windows.
62944     buf_ = base::PagedMemory::Allocate(capacity_);
62945 
62946     // Surely we are going to use at least the first page, but we may not need
62947     // the rest for a bit.
62948     const auto page_size = base::GetSysPageSize();
62949     buf_.AdviseDontNeed(buf() + page_size, capacity_ - page_size);
62950   }
62951 
62952   PERFETTO_CHECK(capacity_ > size_);
62953   return ReceiveBuffer{buf() + size_, capacity_ - size_};
62954 }
62955 
EndReceive(size_t recv_size)62956 bool BufferedFrameDeserializer::EndReceive(size_t recv_size) {
62957   const auto page_size = base::GetSysPageSize();
62958   PERFETTO_CHECK(recv_size + size_ <= capacity_);
62959   size_ += recv_size;
62960 
62961   // At this point the contents buf_ can contain:
62962   // A) Only a fragment of the header (the size of the frame). E.g.,
62963   //    03 00 00 (the header is 4 bytes, one is missing).
62964   //
62965   // B) A header and a part of the frame. E.g.,
62966   //     05 00 00 00         11 22 33
62967   //    [ header, size=5 ]  [ Partial frame ]
62968   //
62969   // C) One or more complete header+frame. E.g.,
62970   //     05 00 00 00         11 22 33 44 55   03 00 00 00        AA BB CC
62971   //    [ header, size=5 ]  [ Whole frame ]  [ header, size=3 ] [ Whole frame ]
62972   //
62973   // D) Some complete header+frame(s) and a partial header or frame (C + A/B).
62974   //
62975   // C Is the more likely case and the one we are optimizing for. A, B, D can
62976   // happen because of the streaming nature of the socket.
62977   // The invariant of this function is that, when it returns, buf_ is either
62978   // empty (we drained all the complete frames) or starts with the header of the
62979   // next, still incomplete, frame.
62980 
62981   size_t consumed_size = 0;
62982   for (;;) {
62983     if (size_ < consumed_size + kHeaderSize)
62984       break;  // Case A, not enough data to read even the header.
62985 
62986     // Read the header into |payload_size|.
62987     uint32_t payload_size = 0;
62988     const char* rd_ptr = buf() + consumed_size;
62989     memcpy(base::AssumeLittleEndian(&payload_size), rd_ptr, kHeaderSize);
62990 
62991     // Saturate the |payload_size| to prevent overflows. The > capacity_ check
62992     // below will abort the parsing.
62993     size_t next_frame_size =
62994         std::min(static_cast<size_t>(payload_size), capacity_);
62995     next_frame_size += kHeaderSize;
62996     rd_ptr += kHeaderSize;
62997 
62998     if (size_ < consumed_size + next_frame_size) {
62999       // Case B. We got the header but not the whole frame.
63000       if (next_frame_size > capacity_) {
63001         // The caller is expected to shut down the socket and give up at this
63002         // point. If it doesn't do that and insists going on at some point it
63003         // will hit the capacity check in BeginReceive().
63004         PERFETTO_LOG("IPC Frame too large (size %zu)", next_frame_size);
63005         return false;
63006       }
63007       break;
63008     }
63009 
63010     // Case C. We got at least one header and whole frame.
63011     DecodeFrame(rd_ptr, payload_size);
63012     consumed_size += next_frame_size;
63013   }
63014 
63015   PERFETTO_DCHECK(consumed_size <= size_);
63016   if (consumed_size > 0) {
63017     // Shift out the consumed data from the buffer. In the typical case (C)
63018     // there is nothing to shift really, just setting size_ = 0 is enough.
63019     // Shifting is only for the (unlikely) case D.
63020     size_ -= consumed_size;
63021     if (size_ > 0) {
63022       // Case D. We consumed some frames but there is a leftover at the end of
63023       // the buffer. Shift out the consumed bytes, so that on the next round
63024       // |buf_| starts with the header of the next unconsumed frame.
63025       const char* move_begin = buf() + consumed_size;
63026       PERFETTO_CHECK(move_begin > buf());
63027       PERFETTO_CHECK(move_begin + size_ <= buf() + capacity_);
63028       memmove(buf(), move_begin, size_);
63029     }
63030     // If we just finished decoding a large frame that used more than one page,
63031     // release the extra memory in the buffer. Large frames should be quite
63032     // rare.
63033     if (consumed_size > page_size) {
63034       size_t size_rounded_up = (size_ / page_size + 1) * page_size;
63035       if (size_rounded_up < capacity_) {
63036         char* madvise_begin = buf() + size_rounded_up;
63037         const size_t madvise_size = capacity_ - size_rounded_up;
63038         PERFETTO_CHECK(madvise_begin > buf() + size_);
63039         PERFETTO_CHECK(madvise_begin + madvise_size <= buf() + capacity_);
63040         buf_.AdviseDontNeed(madvise_begin, madvise_size);
63041       }
63042     }
63043   }
63044   // At this point |size_| == 0 for case C, > 0 for cases A, B, D.
63045   return true;
63046 }
63047 
PopNextFrame()63048 std::unique_ptr<Frame> BufferedFrameDeserializer::PopNextFrame() {
63049   if (decoded_frames_.empty())
63050     return nullptr;
63051   std::unique_ptr<Frame> frame = std::move(decoded_frames_.front());
63052   decoded_frames_.pop_front();
63053   return frame;
63054 }
63055 
DecodeFrame(const char * data,size_t size)63056 void BufferedFrameDeserializer::DecodeFrame(const char* data, size_t size) {
63057   if (size == 0)
63058     return;
63059   std::unique_ptr<Frame> frame(new Frame);
63060   if (frame->ParseFromArray(data, size))
63061     decoded_frames_.push_back(std::move(frame));
63062 }
63063 
63064 // static
Serialize(const Frame & frame)63065 std::string BufferedFrameDeserializer::Serialize(const Frame& frame) {
63066   std::vector<uint8_t> payload = frame.SerializeAsArray();
63067   const uint32_t payload_size = static_cast<uint32_t>(payload.size());
63068   std::string buf;
63069   buf.resize(kHeaderSize + payload_size);
63070   memcpy(&buf[0], base::AssumeLittleEndian(&payload_size), kHeaderSize);
63071   memcpy(&buf[kHeaderSize], payload.data(), payload.size());
63072   return buf;
63073 }
63074 
63075 }  // namespace ipc
63076 }  // namespace perfetto
63077 // gen_amalgamated begin source: src/ipc/deferred.cc
63078 // gen_amalgamated begin header: include/perfetto/ext/ipc/deferred.h
63079 // gen_amalgamated begin header: include/perfetto/ext/ipc/async_result.h
63080 /*
63081  * Copyright (C) 2017 The Android Open Source Project
63082  *
63083  * Licensed under the Apache License, Version 2.0 (the "License");
63084  * you may not use this file except in compliance with the License.
63085  * You may obtain a copy of the License at
63086  *
63087  *      http://www.apache.org/licenses/LICENSE-2.0
63088  *
63089  * Unless required by applicable law or agreed to in writing, software
63090  * distributed under the License is distributed on an "AS IS" BASIS,
63091  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
63092  * See the License for the specific language governing permissions and
63093  * limitations under the License.
63094  */
63095 
63096 #ifndef INCLUDE_PERFETTO_EXT_IPC_ASYNC_RESULT_H_
63097 #define INCLUDE_PERFETTO_EXT_IPC_ASYNC_RESULT_H_
63098 
63099 #include <memory>
63100 #include <type_traits>
63101 #include <utility>
63102 
63103 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
63104 
63105 namespace perfetto {
63106 namespace ipc {
63107 
63108 // Wraps the result of an asynchronous invocation. This is the equivalent of a
63109 // std::pair<unique_ptr<T>, bool> with syntactic sugar. It is used as callback
63110 // argument by Deferred<T>. T is a ProtoMessage subclass (i.e. generated .pb.h).
63111 template <typename T>
63112 class AsyncResult {
63113  public:
Create()63114   static AsyncResult Create() {
63115     return AsyncResult(std::unique_ptr<T>(new T()));
63116   }
63117 
AsyncResult(std::unique_ptr<T> msg=nullptr,bool has_more=false,int fd=-1)63118   AsyncResult(std::unique_ptr<T> msg = nullptr,
63119               bool has_more = false,
63120               int fd = -1)
63121       : msg_(std::move(msg)), has_more_(has_more), fd_(fd) {
63122     static_assert(std::is_base_of<ProtoMessage, T>::value, "T->ProtoMessage");
63123   }
63124   AsyncResult(AsyncResult&&) noexcept = default;
63125   AsyncResult& operator=(AsyncResult&&) = default;
63126 
success() const63127   bool success() const { return !!msg_; }
operator bool() const63128   explicit operator bool() const { return success(); }
63129 
has_more() const63130   bool has_more() const { return has_more_; }
set_has_more(bool has_more)63131   void set_has_more(bool has_more) { has_more_ = has_more; }
63132 
set_msg(std::unique_ptr<T> msg)63133   void set_msg(std::unique_ptr<T> msg) { msg_ = std::move(msg); }
release_msg()63134   T* release_msg() { return msg_.release(); }
operator ->()63135   T* operator->() { return msg_.get(); }
operator *()63136   T& operator*() { return *msg_; }
63137 
set_fd(int fd)63138   void set_fd(int fd) { fd_ = fd; }
fd() const63139   int fd() const { return fd_; }
63140 
63141  private:
63142   std::unique_ptr<T> msg_;
63143   bool has_more_ = false;
63144 
63145   // Optional. Only for messages that convey a file descriptor, for sharing
63146   // memory across processes.
63147   int fd_ = -1;
63148 };
63149 
63150 }  // namespace ipc
63151 }  // namespace perfetto
63152 
63153 #endif  // INCLUDE_PERFETTO_EXT_IPC_ASYNC_RESULT_H_
63154 /*
63155  * Copyright (C) 2017 The Android Open Source Project
63156  *
63157  * Licensed under the Apache License, Version 2.0 (the "License");
63158  * you may not use this file except in compliance with the License.
63159  * You may obtain a copy of the License at
63160  *
63161  *      http://www.apache.org/licenses/LICENSE-2.0
63162  *
63163  * Unless required by applicable law or agreed to in writing, software
63164  * distributed under the License is distributed on an "AS IS" BASIS,
63165  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
63166  * See the License for the specific language governing permissions and
63167  * limitations under the License.
63168  */
63169 
63170 #ifndef INCLUDE_PERFETTO_EXT_IPC_DEFERRED_H_
63171 #define INCLUDE_PERFETTO_EXT_IPC_DEFERRED_H_
63172 
63173 #include <functional>
63174 #include <memory>
63175 #include <utility>
63176 
63177 // gen_amalgamated expanded: #include "perfetto/ext/ipc/async_result.h"
63178 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
63179 
63180 namespace perfetto {
63181 namespace ipc {
63182 
63183 // This class is a wrapper for a callback handling async results.
63184 // The problem this is solving is the following: For each result argument of the
63185 // methods generated from the .proto file:
63186 // - The client wants to see something on which it can Bind() a callback, which
63187 //   is invoked asynchronously once reply is received from the host.
63188 // - The host wants to expose something to user code that implements the IPC
63189 //   methods to allow them to provide an asynchronous reply back to the client.
63190 //   Eventually even more than once, for the case streaming replies.
63191 //
63192 // In both cases we want to make sure that callbacks don't get lost along the
63193 // way. To address this, this class will automatically reject the callbacks
63194 // if they are not resolved at destructor time (or the object is std::move()'d).
63195 //
63196 // The client is supposed to use this class as follows:
63197 //   class GreeterProxy {
63198 //      void SayHello(const HelloRequest&, Deferred<HelloReply> reply)
63199 //   }
63200 //  ...
63201 //  Deferred<HelloReply> reply;
63202 //  reply.Bind([] (AsyncResult<HelloReply> reply) {
63203 //    std::cout << reply.success() ? reply->message : "failure";
63204 //  });
63205 //  host_proxy_instance.SayHello(req, std::move(reply));
63206 //
63207 // The host instead is supposed to use this as follows:
63208 //   class GreeterImpl : public Greeter {
63209 //     void SayHello(const HelloRequest& req, Deferred<HelloReply> reply) {
63210 //        AsyncResult<HelloReply> reply = AsyncResult<HelloReply>::Create();
63211 //        reply->set_greeting("Hello " + req.name)
63212 //        reply.Resolve(std::move(reply));
63213 //     }
63214 //   }
63215 // Or for more complex cases, the deferred object can be std::move()'d outside
63216 // and the reply can continue asynchronously later.
63217 
63218 template <typename T>
63219 class Deferred;
63220 
63221 class DeferredBase {
63222  public:
63223   explicit DeferredBase(
63224       std::function<void(AsyncResult<ProtoMessage>)> callback = nullptr);
63225 
63226   template <typename T>
DeferredBase(Deferred<T> other)63227   explicit DeferredBase(Deferred<T> other)
63228       : callback_(std::move(other.callback_)) {}
63229 
63230   ~DeferredBase();
63231   DeferredBase(DeferredBase&&) noexcept;
63232   DeferredBase& operator=(DeferredBase&&);
63233   void Bind(std::function<void(AsyncResult<ProtoMessage>)> callback);
63234   bool IsBound() const;
63235   void Resolve(AsyncResult<ProtoMessage>);
63236   void Reject();
63237 
63238  protected:
63239   template <typename T>
63240   friend class Deferred;
63241   void Move(DeferredBase&);
63242 
63243   std::function<void(AsyncResult<ProtoMessage>)> callback_;
63244 };
63245 
63246 template <typename T>  // T : ProtoMessage subclass
63247 class Deferred : public DeferredBase {
63248  public:
Deferred(std::function<void (AsyncResult<T>)> callback=nullptr)63249   explicit Deferred(std::function<void(AsyncResult<T>)> callback = nullptr) {
63250     Bind(std::move(callback));
63251   }
63252 
63253   // This move constructor (and the similar one in DeferredBase) is meant to be
63254   // called only by the autogenerated code. The caller has to guarantee that the
63255   // moved-from and moved-to types match. The behavior is otherwise undefined.
Deferred(DeferredBase && other)63256   explicit Deferred(DeferredBase&& other) {
63257     callback_ = std::move(other.callback_);
63258     other.callback_ = nullptr;
63259   }
63260 
Bind(std::function<void (AsyncResult<T>)> callback)63261   void Bind(std::function<void(AsyncResult<T>)> callback) {
63262     if (!callback)
63263       return;
63264 
63265     // Here we need a callback adapter to downcast the callback to a generic
63266     // callback that takes an AsyncResult<ProtoMessage>, so that it can be
63267     // stored in the base class |callback_|.
63268     auto callback_adapter = [callback](
63269                                 AsyncResult<ProtoMessage> async_result_base) {
63270       // Upcast the async_result from <ProtoMessage> -> <T : ProtoMessage>.
63271       static_assert(std::is_base_of<ProtoMessage, T>::value, "T:ProtoMessage");
63272       AsyncResult<T> async_result(
63273           std::unique_ptr<T>(static_cast<T*>(async_result_base.release_msg())),
63274           async_result_base.has_more(), async_result_base.fd());
63275       callback(std::move(async_result));
63276     };
63277     DeferredBase::Bind(callback_adapter);
63278   }
63279 
63280   // If no more messages are expected, |callback_| is released.
Resolve(AsyncResult<T> async_result)63281   void Resolve(AsyncResult<T> async_result) {
63282     // Convert the |async_result| to the generic base one (T -> ProtoMessage).
63283     AsyncResult<ProtoMessage> async_result_base(
63284         std::unique_ptr<ProtoMessage>(async_result.release_msg()),
63285         async_result.has_more(), async_result.fd());
63286     DeferredBase::Resolve(std::move(async_result_base));
63287   }
63288 };
63289 
63290 }  // namespace ipc
63291 }  // namespace perfetto
63292 
63293 #endif  // INCLUDE_PERFETTO_EXT_IPC_DEFERRED_H_
63294 /*
63295  * Copyright (C) 2017 The Android Open Source Project
63296  *
63297  * Licensed under the Apache License, Version 2.0 (the "License");
63298  * you may not use this file except in compliance with the License.
63299  * You may obtain a copy of the License at
63300  *
63301  *      http://www.apache.org/licenses/LICENSE-2.0
63302  *
63303  * Unless required by applicable law or agreed to in writing, software
63304  * distributed under the License is distributed on an "AS IS" BASIS,
63305  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
63306  * See the License for the specific language governing permissions and
63307  * limitations under the License.
63308  */
63309 
63310 // gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
63311 
63312 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
63313 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
63314 
63315 namespace perfetto {
63316 namespace ipc {
63317 
DeferredBase(std::function<void (AsyncResult<ProtoMessage>)> callback)63318 DeferredBase::DeferredBase(
63319     std::function<void(AsyncResult<ProtoMessage>)> callback)
63320     : callback_(std::move(callback)) {}
63321 
~DeferredBase()63322 DeferredBase::~DeferredBase() {
63323   if (callback_)
63324     Reject();
63325 }
63326 
63327 // Can't just use "= default" here because the default move operator for
63328 // std::function doesn't necessarily swap and hence can leave a copy of the
63329 // bind state around, which is undesirable.
DeferredBase(DeferredBase && other)63330 DeferredBase::DeferredBase(DeferredBase&& other) noexcept {
63331   Move(other);
63332 }
63333 
operator =(DeferredBase && other)63334 DeferredBase& DeferredBase::operator=(DeferredBase&& other) {
63335   if (callback_)
63336     Reject();
63337   Move(other);
63338   return *this;
63339 }
63340 
Move(DeferredBase & other)63341 void DeferredBase::Move(DeferredBase& other) {
63342   callback_ = std::move(other.callback_);
63343   other.callback_ = nullptr;
63344 }
63345 
Bind(std::function<void (AsyncResult<ProtoMessage>)> callback)63346 void DeferredBase::Bind(
63347     std::function<void(AsyncResult<ProtoMessage>)> callback) {
63348   callback_ = std::move(callback);
63349 }
63350 
IsBound() const63351 bool DeferredBase::IsBound() const {
63352   return !!callback_;
63353 }
63354 
Resolve(AsyncResult<ProtoMessage> async_result)63355 void DeferredBase::Resolve(AsyncResult<ProtoMessage> async_result) {
63356   if (!callback_) {
63357     PERFETTO_DFATAL("No callback set.");
63358     return;
63359   }
63360   bool has_more = async_result.has_more();
63361   callback_(std::move(async_result));
63362   if (!has_more)
63363     callback_ = nullptr;
63364 }
63365 
63366 // Resolves with a nullptr |msg_|, signalling failure to |callback_|.
Reject()63367 void DeferredBase::Reject() {
63368   Resolve(AsyncResult<ProtoMessage>());
63369 }
63370 
63371 }  // namespace ipc
63372 }  // namespace perfetto
63373 // gen_amalgamated begin source: src/ipc/virtual_destructors.cc
63374 // gen_amalgamated begin header: include/perfetto/ext/ipc/client.h
63375 /*
63376  * Copyright (C) 2017 The Android Open Source Project
63377  *
63378  * Licensed under the Apache License, Version 2.0 (the "License");
63379  * you may not use this file except in compliance with the License.
63380  * You may obtain a copy of the License at
63381  *
63382  *      http://www.apache.org/licenses/LICENSE-2.0
63383  *
63384  * Unless required by applicable law or agreed to in writing, software
63385  * distributed under the License is distributed on an "AS IS" BASIS,
63386  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
63387  * See the License for the specific language governing permissions and
63388  * limitations under the License.
63389  */
63390 
63391 #ifndef INCLUDE_PERFETTO_EXT_IPC_CLIENT_H_
63392 #define INCLUDE_PERFETTO_EXT_IPC_CLIENT_H_
63393 
63394 #include <functional>
63395 #include <memory>
63396 
63397 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
63398 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
63399 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
63400 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
63401 
63402 namespace perfetto {
63403 
63404 namespace base {
63405 class TaskRunner;
63406 }  // namespace base
63407 
63408 namespace ipc {
63409 class ServiceProxy;
63410 
63411 // The client-side class that talks to the host over the socket and multiplexes
63412 // requests coming from the various autogenerated ServiceProxy stubs.
63413 // This is meant to be used by the user code as follows:
63414 // auto client = Client::CreateInstance("socket_name", task_runner);
63415 // std::unique_ptr<GreeterService> svc(new GreeterService());
63416 // client.BindService(svc);
63417 // svc.OnConnect([] () {
63418 //    svc.SayHello(..., ...);
63419 // });
63420 class Client {
63421  public:
63422   // struct ConnArgs is used for creating a client in 2 connection modes:
63423   // 1. Connect using a socket name with the option to retry the connection on
63424   //    connection failure.
63425   // 2. Adopt a connected socket.
63426   struct ConnArgs {
ConnArgsperfetto::ipc::Client::ConnArgs63427     ConnArgs(const char* sock_name, bool sock_retry)
63428         : socket_name(sock_name), retry(sock_retry) {}
ConnArgsperfetto::ipc::Client::ConnArgs63429     explicit ConnArgs(base::ScopedSocketHandle sock_fd)
63430         : socket_fd(std::move(sock_fd)) {}
63431 
63432     // Disallow copy. Only supports move.
63433     ConnArgs(const ConnArgs& other) = delete;
63434     ConnArgs(ConnArgs&& other) = default;
63435 
63436     base::ScopedSocketHandle socket_fd;
63437     const char* socket_name = nullptr;
63438     bool retry = false;  // Only for connecting with |socket_name|.
63439   };
63440 
63441   static std::unique_ptr<Client> CreateInstance(ConnArgs, base::TaskRunner*);
63442   virtual ~Client();
63443 
63444   virtual void BindService(base::WeakPtr<ServiceProxy>) = 0;
63445 
63446   // There is no need to call this method explicitly. Destroying the
63447   // ServiceProxy instance is sufficient and will automatically unbind it. This
63448   // method is exposed only for the ServiceProxy destructor.
63449   virtual void UnbindService(ServiceID) = 0;
63450 
63451   // Returns (with move semantics) the last file descriptor received on the IPC
63452   // channel. No buffering is performed: if a service sends two file descriptors
63453   // and the caller doesn't read them immediately, the first one will be
63454   // automatically closed when the second is received (and will hit a DCHECK in
63455   // debug builds).
63456   virtual base::ScopedFile TakeReceivedFD() = 0;
63457 };
63458 
63459 }  // namespace ipc
63460 }  // namespace perfetto
63461 
63462 #endif  // INCLUDE_PERFETTO_EXT_IPC_CLIENT_H_
63463 // gen_amalgamated begin header: include/perfetto/ext/ipc/host.h
63464 /*
63465  * Copyright (C) 2017 The Android Open Source Project
63466  *
63467  * Licensed under the Apache License, Version 2.0 (the "License");
63468  * you may not use this file except in compliance with the License.
63469  * You may obtain a copy of the License at
63470  *
63471  *      http://www.apache.org/licenses/LICENSE-2.0
63472  *
63473  * Unless required by applicable law or agreed to in writing, software
63474  * distributed under the License is distributed on an "AS IS" BASIS,
63475  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
63476  * See the License for the specific language governing permissions and
63477  * limitations under the License.
63478  */
63479 
63480 #ifndef INCLUDE_PERFETTO_EXT_IPC_HOST_H_
63481 #define INCLUDE_PERFETTO_EXT_IPC_HOST_H_
63482 
63483 #include <memory>
63484 
63485 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
63486 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
63487 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
63488 
63489 namespace perfetto {
63490 
63491 namespace base {
63492 class TaskRunner;
63493 }  // namespace base
63494 
63495 namespace ipc {
63496 
63497 class Service;
63498 
63499 // The host-side of the IPC layer. This class acts as a registry and request
63500 // dispatcher. It listen on the UnixSocket |socket_name| for incoming requests
63501 // (coming Client instances) and dispatches their requests to the various
63502 // Services exposed.
63503 class Host {
63504  public:
63505   // Creates an instance and starts listening on the given |socket_name|.
63506   // Returns nullptr if listening on the socket fails.
63507   static std::unique_ptr<Host> CreateInstance(const char* socket_name,
63508                                               base::TaskRunner*);
63509 
63510   // Like the above but takes a file descriptor to a pre-bound unix socket.
63511   // Returns nullptr if listening on the socket fails.
63512   static std::unique_ptr<Host> CreateInstance(base::ScopedSocketHandle,
63513                                               base::TaskRunner*);
63514 
63515   virtual ~Host();
63516 
63517   // Registers a new service and makes it available to remote IPC peers.
63518   // All the exposed Service instances will be destroyed when destroying the
63519   // Host instance if ExposeService succeeds and returns true, or immediately
63520   // after the call in case of failure.
63521   // Returns true if the register has been successfully registered, false in
63522   // case of errors (e.g., another service with the same name is already
63523   // registered).
63524   virtual bool ExposeService(std::unique_ptr<Service>) = 0;
63525 };
63526 
63527 }  // namespace ipc
63528 }  // namespace perfetto
63529 
63530 #endif  // INCLUDE_PERFETTO_EXT_IPC_HOST_H_
63531 // gen_amalgamated begin header: include/perfetto/ext/ipc/service.h
63532 // gen_amalgamated begin header: include/perfetto/ext/ipc/client_info.h
63533 /*
63534  * Copyright (C) 2017 The Android Open Source Project
63535  *
63536  * Licensed under the Apache License, Version 2.0 (the "License");
63537  * you may not use this file except in compliance with the License.
63538  * You may obtain a copy of the License at
63539  *
63540  *      http://www.apache.org/licenses/LICENSE-2.0
63541  *
63542  * Unless required by applicable law or agreed to in writing, software
63543  * distributed under the License is distributed on an "AS IS" BASIS,
63544  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
63545  * See the License for the specific language governing permissions and
63546  * limitations under the License.
63547  */
63548 
63549 #ifndef INCLUDE_PERFETTO_EXT_IPC_CLIENT_INFO_H_
63550 #define INCLUDE_PERFETTO_EXT_IPC_CLIENT_INFO_H_
63551 
63552 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
63553 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
63554 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
63555 
63556 namespace perfetto {
63557 namespace ipc {
63558 
63559 // Passed to Service(s) to identify remote clients.
63560 class ClientInfo {
63561  public:
63562   ClientInfo() = default;
ClientInfo(ClientID client_id,uid_t uid)63563   ClientInfo(ClientID client_id, uid_t uid)
63564       : client_id_(client_id), uid_(uid) {}
63565 
operator ==(const ClientInfo & other) const63566   bool operator==(const ClientInfo& other) const {
63567     return (client_id_ == other.client_id_ && uid_ == other.uid_);
63568   }
operator !=(const ClientInfo & other) const63569   bool operator!=(const ClientInfo& other) const { return !(*this == other); }
63570 
63571   // For map<> and other sorted containers.
operator <(const ClientInfo & other) const63572   bool operator<(const ClientInfo& other) const {
63573     PERFETTO_DCHECK(client_id_ != other.client_id_ || *this == other);
63574     return client_id_ < other.client_id_;
63575   }
63576 
is_valid() const63577   bool is_valid() const { return client_id_ != 0; }
63578 
63579   // A monotonic counter.
client_id() const63580   ClientID client_id() const { return client_id_; }
63581 
63582   // Posix User ID. Comes from the kernel, can be trusted.
uid() const63583   uid_t uid() const { return uid_; }
63584 
63585  private:
63586   ClientID client_id_ = 0;
63587   uid_t uid_ = kInvalidUid;
63588 };
63589 
63590 }  // namespace ipc
63591 }  // namespace perfetto
63592 
63593 #endif  // INCLUDE_PERFETTO_EXT_IPC_CLIENT_INFO_H_
63594 /*
63595  * Copyright (C) 2017 The Android Open Source Project
63596  *
63597  * Licensed under the Apache License, Version 2.0 (the "License");
63598  * you may not use this file except in compliance with the License.
63599  * You may obtain a copy of the License at
63600  *
63601  *      http://www.apache.org/licenses/LICENSE-2.0
63602  *
63603  * Unless required by applicable law or agreed to in writing, software
63604  * distributed under the License is distributed on an "AS IS" BASIS,
63605  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
63606  * See the License for the specific language governing permissions and
63607  * limitations under the License.
63608  */
63609 
63610 #ifndef INCLUDE_PERFETTO_EXT_IPC_SERVICE_H_
63611 #define INCLUDE_PERFETTO_EXT_IPC_SERVICE_H_
63612 
63613 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
63614 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
63615 // gen_amalgamated expanded: #include "perfetto/ext/ipc/client_info.h"
63616 
63617 namespace perfetto {
63618 namespace ipc {
63619 
63620 class ServiceDescriptor;
63621 
63622 // The base class for all the autogenerated host-side service interfaces.
63623 class Service {
63624  public:
63625   virtual ~Service();
63626 
63627   // Overridden by the auto-generated class. Provides the list of methods and
63628   // the protobuf (de)serialization functions for their arguments.
63629   virtual const ServiceDescriptor& GetDescriptor() = 0;
63630 
63631   // Invoked when a remote client disconnects. Use client_info() to obtain
63632   // details about the client that disconnected.
OnClientDisconnected()63633   virtual void OnClientDisconnected() {}
63634 
63635   // Returns the ClientInfo for the current IPC request. Returns an invalid
63636   // ClientInfo if called outside the scope of an IPC method.
client_info()63637   const ClientInfo& client_info() {
63638     PERFETTO_DCHECK(client_info_.is_valid());
63639     return client_info_;
63640   }
63641 
TakeReceivedFD()63642   base::ScopedFile TakeReceivedFD() {
63643     if (received_fd_)
63644       return std::move(*received_fd_);
63645     return base::ScopedFile();
63646   }
63647 
63648  private:
63649   friend class HostImpl;
63650   ClientInfo client_info_;
63651   // This is a pointer because the received fd needs to remain owned by the
63652   // ClientConnection, as we will provide it to all method invocations
63653   // for that client until one of them calls Service::TakeReceivedFD.
63654   //
63655   // Different clients might have sent different FDs so this cannot be owned
63656   // here.
63657   //
63658   // Note that this means that there can always only be one outstanding
63659   // invocation per client that supplies an FD and the client needs to
63660   // wait for this one to return before calling another one.
63661   base::ScopedFile* received_fd_;
63662 };
63663 
63664 }  // namespace ipc
63665 }  // namespace perfetto
63666 
63667 #endif  // INCLUDE_PERFETTO_EXT_IPC_SERVICE_H_
63668 // gen_amalgamated begin header: include/perfetto/ext/ipc/service_proxy.h
63669 /*
63670  * Copyright (C) 2017 The Android Open Source Project
63671  *
63672  * Licensed under the Apache License, Version 2.0 (the "License");
63673  * you may not use this file except in compliance with the License.
63674  * You may obtain a copy of the License at
63675  *
63676  *      http://www.apache.org/licenses/LICENSE-2.0
63677  *
63678  * Unless required by applicable law or agreed to in writing, software
63679  * distributed under the License is distributed on an "AS IS" BASIS,
63680  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
63681  * See the License for the specific language governing permissions and
63682  * limitations under the License.
63683  */
63684 
63685 #ifndef INCLUDE_PERFETTO_EXT_IPC_SERVICE_PROXY_H_
63686 #define INCLUDE_PERFETTO_EXT_IPC_SERVICE_PROXY_H_
63687 
63688 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
63689 
63690 #include <assert.h>
63691 
63692 #include <functional>
63693 #include <map>
63694 #include <memory>
63695 #include <string>
63696 
63697 // gen_amalgamated expanded: #include "perfetto/base/export.h"
63698 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
63699 // gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
63700 
63701 namespace perfetto {
63702 namespace ipc {
63703 
63704 class Client;
63705 class ServiceDescriptor;
63706 
63707 // The base class for the client-side autogenerated stubs that forward method
63708 // invocations to the host. All the methods of this class are meant to be called
63709 // only by the autogenerated code.
63710 class PERFETTO_EXPORT ServiceProxy {
63711  public:
63712   class EventListener {
63713    public:
63714     virtual ~EventListener();
63715 
63716     // Called once after Client::BindService() if the ServiceProxy has been
63717     // successfully bound to the host. It is possible to start sending IPC
63718     // requests soon after this.
OnConnect()63719     virtual void OnConnect() {}
63720 
63721     // Called if the connection fails to be established or drops after having
63722     // been established.
OnDisconnect()63723     virtual void OnDisconnect() {}
63724   };
63725 
63726   // Guarantees that no callback will happen after this object has been
63727   // destroyed. The caller has to guarantee that the |event_listener| stays
63728   // alive at least as long as the ServiceProxy instance.
63729   explicit ServiceProxy(EventListener*);
63730   virtual ~ServiceProxy();
63731 
63732   void InitializeBinding(base::WeakPtr<Client>,
63733                          ServiceID,
63734                          std::map<std::string, MethodID>);
63735 
63736   // Called by the IPC methods in the autogenerated classes.
63737   void BeginInvoke(const std::string& method_name,
63738                    const ProtoMessage& request,
63739                    DeferredBase reply,
63740                    int fd = -1);
63741 
63742   // Called by ClientImpl.
63743   // |reply_args| == nullptr means request failure.
63744   void EndInvoke(RequestID,
63745                  std::unique_ptr<ProtoMessage> reply_arg,
63746                  bool has_more);
63747 
63748   // Called by ClientImpl.
63749   void OnConnect(bool success);
63750   void OnDisconnect();
connected() const63751   bool connected() const { return service_id_ != 0; }
63752 
63753   base::WeakPtr<ServiceProxy> GetWeakPtr() const;
63754 
63755   // Implemented by the autogenerated class.
63756   virtual const ServiceDescriptor& GetDescriptor() = 0;
63757 
63758  private:
63759   base::WeakPtr<Client> client_;
63760   ServiceID service_id_ = 0;
63761   std::map<std::string, MethodID> remote_method_ids_;
63762   std::map<RequestID, DeferredBase> pending_callbacks_;
63763   EventListener* const event_listener_;
63764   base::WeakPtrFactory<ServiceProxy> weak_ptr_factory_;  // Keep last.
63765 };
63766 
63767 }  // namespace ipc
63768 }  // namespace perfetto
63769 
63770 #endif  // INCLUDE_PERFETTO_EXT_IPC_SERVICE_PROXY_H_
63771 /*
63772  * Copyright (C) 2018 The Android Open Source Project
63773  *
63774  * Licensed under the Apache License, Version 2.0 (the "License");
63775  * you may not use this file except in compliance with the License.
63776  * You may obtain a copy of the License at
63777  *
63778  *      http://www.apache.org/licenses/LICENSE-2.0
63779  *
63780  * Unless required by applicable law or agreed to in writing, software
63781  * distributed under the License is distributed on an "AS IS" BASIS,
63782  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
63783  * See the License for the specific language governing permissions and
63784  * limitations under the License.
63785  */
63786 
63787 // gen_amalgamated expanded: #include "perfetto/ext/ipc/client.h"
63788 // gen_amalgamated expanded: #include "perfetto/ext/ipc/host.h"
63789 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
63790 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
63791 
63792 // This translation unit contains the definitions for the destructor of pure
63793 // virtual interfaces for the current build target. The alternative would be
63794 // introducing a one-liner .cc file for each pure virtual interface, which is
63795 // overkill. This is for compliance with -Wweak-vtables.
63796 
63797 namespace perfetto {
63798 namespace ipc {
63799 
63800 Client::~Client() = default;
63801 Host::~Host() = default;
63802 Service::~Service() = default;
63803 ServiceProxy::EventListener::~EventListener() = default;
63804 
63805 }  // namespace ipc
63806 }  // namespace perfetto
63807 // gen_amalgamated begin source: src/ipc/client_impl.cc
63808 // gen_amalgamated begin header: src/ipc/client_impl.h
63809 /*
63810  * Copyright (C) 2017 The Android Open Source Project
63811  *
63812  * Licensed under the Apache License, Version 2.0 (the "License");
63813  * you may not use this file except in compliance with the License.
63814  * You may obtain a copy of the License at
63815  *
63816  *      http://www.apache.org/licenses/LICENSE-2.0
63817  *
63818  * Unless required by applicable law or agreed to in writing, software
63819  * distributed under the License is distributed on an "AS IS" BASIS,
63820  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
63821  * See the License for the specific language governing permissions and
63822  * limitations under the License.
63823  */
63824 
63825 #ifndef SRC_IPC_CLIENT_IMPL_H_
63826 #define SRC_IPC_CLIENT_IMPL_H_
63827 
63828 #include <list>
63829 #include <map>
63830 #include <memory>
63831 
63832 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
63833 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
63834 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
63835 // gen_amalgamated expanded: #include "perfetto/ext/ipc/client.h"
63836 // gen_amalgamated expanded: #include "src/ipc/buffered_frame_deserializer.h"
63837 
63838 namespace perfetto {
63839 
63840 namespace protos {
63841 namespace gen {
63842 class IPCFrame_BindServiceReply;
63843 class IPCFrame_InvokeMethodReply;
63844 }  // namespace gen
63845 }  // namespace protos
63846 
63847 namespace base {
63848 class TaskRunner;
63849 }  // namespace base
63850 
63851 namespace ipc {
63852 
63853 class ServiceDescriptor;
63854 
63855 class ClientImpl : public Client, public base::UnixSocket::EventListener {
63856  public:
63857   ClientImpl(ConnArgs, base::TaskRunner*);
63858   ~ClientImpl() override;
63859 
63860   // Client implementation.
63861   void BindService(base::WeakPtr<ServiceProxy>) override;
63862   void UnbindService(ServiceID) override;
63863   base::ScopedFile TakeReceivedFD() override;
63864 
63865   // base::UnixSocket::EventListener implementation.
63866   void OnConnect(base::UnixSocket*, bool connected) override;
63867   void OnDisconnect(base::UnixSocket*) override;
63868   void OnDataAvailable(base::UnixSocket*) override;
63869 
63870   RequestID BeginInvoke(ServiceID,
63871                         const std::string& method_name,
63872                         MethodID remote_method_id,
63873                         const ProtoMessage& method_args,
63874                         bool drop_reply,
63875                         base::WeakPtr<ServiceProxy>,
63876                         int fd = -1);
63877 
GetUnixSocketForTesting()63878   base::UnixSocket* GetUnixSocketForTesting() { return sock_.get(); }
63879 
63880  private:
63881   struct QueuedRequest {
63882     QueuedRequest();
63883     int type = 0;  // From Frame::msg_case(), see wire_protocol.proto.
63884     RequestID request_id = 0;
63885     base::WeakPtr<ServiceProxy> service_proxy;
63886 
63887     // Only for type == kMsgInvokeMethod.
63888     std::string method_name;
63889   };
63890 
63891   ClientImpl(const ClientImpl&) = delete;
63892   ClientImpl& operator=(const ClientImpl&) = delete;
63893 
63894   void TryConnect();
63895   bool SendFrame(const Frame&, int fd = -1);
63896   void OnFrameReceived(const Frame&);
63897   void OnBindServiceReply(QueuedRequest,
63898                           const protos::gen::IPCFrame_BindServiceReply&);
63899   void OnInvokeMethodReply(QueuedRequest,
63900                            const protos::gen::IPCFrame_InvokeMethodReply&);
63901 
63902   bool invoking_method_reply_ = false;
63903   const char* socket_name_ = nullptr;
63904   bool socket_retry_ = false;
63905   uint32_t socket_backoff_ms_ = 0;
63906   std::unique_ptr<base::UnixSocket> sock_;
63907   base::TaskRunner* const task_runner_;
63908   RequestID last_request_id_ = 0;
63909   BufferedFrameDeserializer frame_deserializer_;
63910   base::ScopedFile received_fd_;
63911   std::map<RequestID, QueuedRequest> queued_requests_;
63912   std::map<ServiceID, base::WeakPtr<ServiceProxy>> service_bindings_;
63913 
63914   // Queue of calls to BindService() that happened before the socket connected.
63915   std::list<base::WeakPtr<ServiceProxy>> queued_bindings_;
63916 
63917   base::WeakPtrFactory<Client> weak_ptr_factory_;  // Keep last.
63918 };
63919 
63920 }  // namespace ipc
63921 }  // namespace perfetto
63922 
63923 #endif  // SRC_IPC_CLIENT_IMPL_H_
63924 // gen_amalgamated begin header: include/perfetto/ext/ipc/service_descriptor.h
63925 /*
63926  * Copyright (C) 2017 The Android Open Source Project
63927  *
63928  * Licensed under the Apache License, Version 2.0 (the "License");
63929  * you may not use this file except in compliance with the License.
63930  * You may obtain a copy of the License at
63931  *
63932  *      http://www.apache.org/licenses/LICENSE-2.0
63933  *
63934  * Unless required by applicable law or agreed to in writing, software
63935  * distributed under the License is distributed on an "AS IS" BASIS,
63936  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
63937  * See the License for the specific language governing permissions and
63938  * limitations under the License.
63939  */
63940 
63941 #ifndef INCLUDE_PERFETTO_EXT_IPC_SERVICE_DESCRIPTOR_H_
63942 #define INCLUDE_PERFETTO_EXT_IPC_SERVICE_DESCRIPTOR_H_
63943 
63944 #include <functional>
63945 #include <string>
63946 #include <utility>
63947 #include <vector>
63948 
63949 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
63950 // gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
63951 
63952 namespace perfetto {
63953 namespace ipc {
63954 
63955 class Service;
63956 
63957 // This is a pure data structure which holds factory methods and strings for the
63958 // services and their methods that get generated in the .h/.cc files.
63959 // Each autogenerated class has a GetDescriptor() method that returns one
63960 // instance of these and allows both client and hosts to map service and method
63961 // names to IDs and provide function pointers to the protobuf decoder fuctions.
63962 class ServiceDescriptor {
63963  public:
63964   struct Method {
63965     const char* name;
63966 
63967     // DecoderFunc is pointer to a function that takes a string in input
63968     // containing protobuf encoded data and returns a decoded protobuf message.
63969     using DecoderFunc = std::unique_ptr<ProtoMessage> (*)(const std::string&);
63970 
63971     // Function pointer to decode the request argument of the method.
63972     DecoderFunc request_proto_decoder;
63973 
63974     // Function pointer to decoded the reply argument of the method.
63975     DecoderFunc reply_proto_decoder;
63976 
63977     // Function pointer that dispatches the generic request to the corresponding
63978     // method implementation.
63979     using InvokerFunc = void (*)(Service*,
63980                                  const ProtoMessage& /* request_args */,
63981                                  DeferredBase /* deferred_reply */);
63982     InvokerFunc invoker;
63983   };
63984 
63985   const char* service_name = nullptr;
63986 
63987   // Note that methods order is not stable. Client and Host might have different
63988   // method indexes, depending on their versions. The Client can't just rely
63989   // on the indexes and has to keep a [string -> remote index] translation map.
63990   std::vector<Method> methods;
63991 };
63992 
63993 }  // namespace ipc
63994 }  // namespace perfetto
63995 
63996 #endif  // INCLUDE_PERFETTO_EXT_IPC_SERVICE_DESCRIPTOR_H_
63997 /*
63998  * Copyright (C) 2017 The Android Open Source Project
63999  *
64000  * Licensed under the Apache License, Version 2.0 (the "License");
64001  * you may not use this file except in compliance with the License.
64002  * You may obtain a copy of the License at
64003  *
64004  *      http://www.apache.org/licenses/LICENSE-2.0
64005  *
64006  * Unless required by applicable law or agreed to in writing, software
64007  * distributed under the License is distributed on an "AS IS" BASIS,
64008  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64009  * See the License for the specific language governing permissions and
64010  * limitations under the License.
64011  */
64012 
64013 // gen_amalgamated expanded: #include "src/ipc/client_impl.h"
64014 
64015 #include <fcntl.h>
64016 #include <inttypes.h>
64017 
64018 #include <utility>
64019 
64020 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
64021 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
64022 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
64023 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_descriptor.h"
64024 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
64025 
64026 // gen_amalgamated expanded: #include "protos/perfetto/ipc/wire_protocol.gen.h"
64027 
64028 // TODO(primiano): Add ThreadChecker everywhere.
64029 
64030 // TODO(primiano): Add timeouts.
64031 
64032 namespace perfetto {
64033 namespace ipc {
64034 
64035 namespace {
64036 constexpr base::SockFamily kClientSockFamily =
64037     kUseTCPSocket ? base::SockFamily::kInet : base::SockFamily::kUnix;
64038 }  // namespace
64039 
64040 // static
CreateInstance(ConnArgs conn_args,base::TaskRunner * task_runner)64041 std::unique_ptr<Client> Client::CreateInstance(ConnArgs conn_args,
64042                                                base::TaskRunner* task_runner) {
64043   std::unique_ptr<Client> client(
64044       new ClientImpl(std::move(conn_args), task_runner));
64045   return client;
64046 }
64047 
ClientImpl(ConnArgs conn_args,base::TaskRunner * task_runner)64048 ClientImpl::ClientImpl(ConnArgs conn_args, base::TaskRunner* task_runner)
64049     : socket_name_(conn_args.socket_name),
64050       socket_retry_(conn_args.retry),
64051       task_runner_(task_runner),
64052       weak_ptr_factory_(this) {
64053   if (conn_args.socket_fd) {
64054     // Create the client using a connected socket. This code path will never hit
64055     // OnConnect().
64056     sock_ = base::UnixSocket::AdoptConnected(
64057         std::move(conn_args.socket_fd), this, task_runner_, kClientSockFamily,
64058         base::SockType::kStream, base::SockPeerCredMode::kIgnore);
64059   } else {
64060     // Connect using the socket name.
64061     TryConnect();
64062   }
64063 }
64064 
~ClientImpl()64065 ClientImpl::~ClientImpl() {
64066   // Ensure we are not destroyed in the middle of invoking a reply.
64067   PERFETTO_DCHECK(!invoking_method_reply_);
64068   OnDisconnect(
64069       nullptr);  // The base::UnixSocket* ptr is not used in OnDisconnect().
64070 }
64071 
TryConnect()64072 void ClientImpl::TryConnect() {
64073   PERFETTO_DCHECK(socket_name_);
64074   sock_ = base::UnixSocket::Connect(socket_name_, this, task_runner_,
64075                                     kClientSockFamily, base::SockType::kStream,
64076                                     base::SockPeerCredMode::kIgnore);
64077 }
64078 
BindService(base::WeakPtr<ServiceProxy> service_proxy)64079 void ClientImpl::BindService(base::WeakPtr<ServiceProxy> service_proxy) {
64080   if (!service_proxy)
64081     return;
64082   if (!sock_->is_connected()) {
64083     queued_bindings_.emplace_back(service_proxy);
64084     return;
64085   }
64086   RequestID request_id = ++last_request_id_;
64087   Frame frame;
64088   frame.set_request_id(request_id);
64089   Frame::BindService* req = frame.mutable_msg_bind_service();
64090   const char* const service_name = service_proxy->GetDescriptor().service_name;
64091   req->set_service_name(service_name);
64092   if (!SendFrame(frame)) {
64093     PERFETTO_DLOG("BindService(%s) failed", service_name);
64094     return service_proxy->OnConnect(false /* success */);
64095   }
64096   QueuedRequest qr;
64097   qr.type = Frame::kMsgBindServiceFieldNumber;
64098   qr.request_id = request_id;
64099   qr.service_proxy = service_proxy;
64100   queued_requests_.emplace(request_id, std::move(qr));
64101 }
64102 
UnbindService(ServiceID service_id)64103 void ClientImpl::UnbindService(ServiceID service_id) {
64104   service_bindings_.erase(service_id);
64105 }
64106 
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)64107 RequestID ClientImpl::BeginInvoke(ServiceID service_id,
64108                                   const std::string& method_name,
64109                                   MethodID remote_method_id,
64110                                   const ProtoMessage& method_args,
64111                                   bool drop_reply,
64112                                   base::WeakPtr<ServiceProxy> service_proxy,
64113                                   int fd) {
64114   RequestID request_id = ++last_request_id_;
64115   Frame frame;
64116   frame.set_request_id(request_id);
64117   Frame::InvokeMethod* req = frame.mutable_msg_invoke_method();
64118   req->set_service_id(service_id);
64119   req->set_method_id(remote_method_id);
64120   req->set_drop_reply(drop_reply);
64121   req->set_args_proto(method_args.SerializeAsString());
64122   if (!SendFrame(frame, fd)) {
64123     PERFETTO_DLOG("BeginInvoke() failed while sending the frame");
64124     return 0;
64125   }
64126   if (drop_reply)
64127     return 0;
64128   QueuedRequest qr;
64129   qr.type = Frame::kMsgInvokeMethodFieldNumber;
64130   qr.request_id = request_id;
64131   qr.method_name = method_name;
64132   qr.service_proxy = std::move(service_proxy);
64133   queued_requests_.emplace(request_id, std::move(qr));
64134   return request_id;
64135 }
64136 
SendFrame(const Frame & frame,int fd)64137 bool ClientImpl::SendFrame(const Frame& frame, int fd) {
64138   // Serialize the frame into protobuf, add the size header, and send it.
64139   std::string buf = BufferedFrameDeserializer::Serialize(frame);
64140 
64141   // TODO(primiano): this should do non-blocking I/O. But then what if the
64142   // socket buffer is full? We might want to either drop the request or throttle
64143   // the send and PostTask the reply later? Right now we are making Send()
64144   // blocking as a workaround. Propagate bakpressure to the caller instead.
64145   bool res = sock_->Send(buf.data(), buf.size(), fd);
64146   PERFETTO_CHECK(res || !sock_->is_connected());
64147   return res;
64148 }
64149 
OnConnect(base::UnixSocket *,bool connected)64150 void ClientImpl::OnConnect(base::UnixSocket*, bool connected) {
64151   if (!connected && socket_retry_) {
64152     socket_backoff_ms_ =
64153         (socket_backoff_ms_ < 10000) ? socket_backoff_ms_ + 1000 : 30000;
64154     PERFETTO_DLOG(
64155         "Connection to traced's UNIX socket failed, retrying in %u seconds",
64156         socket_backoff_ms_ / 1000);
64157     auto weak_this = weak_ptr_factory_.GetWeakPtr();
64158     task_runner_->PostDelayedTask(
64159         [weak_this] {
64160           if (weak_this)
64161             static_cast<ClientImpl&>(*weak_this).TryConnect();
64162         },
64163         socket_backoff_ms_);
64164     return;
64165   }
64166 
64167   // Drain the BindService() calls that were queued before establishing the
64168   // connection with the host. Note that if we got disconnected, the call to
64169   // OnConnect below might delete |this|, so move everything on the stack first.
64170   auto queued_bindings = std::move(queued_bindings_);
64171   queued_bindings_.clear();
64172   for (base::WeakPtr<ServiceProxy>& service_proxy : queued_bindings) {
64173     if (connected) {
64174       BindService(service_proxy);
64175     } else if (service_proxy) {
64176       service_proxy->OnConnect(false /* success */);
64177     }
64178   }
64179   // Don't access |this| below here.
64180 }
64181 
OnDisconnect(base::UnixSocket *)64182 void ClientImpl::OnDisconnect(base::UnixSocket*) {
64183   for (const auto& it : service_bindings_) {
64184     base::WeakPtr<ServiceProxy> service_proxy = it.second;
64185     task_runner_->PostTask([service_proxy] {
64186       if (service_proxy)
64187         service_proxy->OnDisconnect();
64188     });
64189   }
64190   service_bindings_.clear();
64191   queued_bindings_.clear();
64192 }
64193 
OnDataAvailable(base::UnixSocket *)64194 void ClientImpl::OnDataAvailable(base::UnixSocket*) {
64195   size_t rsize;
64196   do {
64197     auto buf = frame_deserializer_.BeginReceive();
64198     base::ScopedFile fd;
64199     rsize = sock_->Receive(buf.data, buf.size, &fd);
64200 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
64201     PERFETTO_DCHECK(!fd);
64202 #else
64203     if (fd) {
64204       PERFETTO_DCHECK(!received_fd_);
64205       int res = fcntl(*fd, F_SETFD, FD_CLOEXEC);
64206       PERFETTO_DCHECK(res == 0);
64207       received_fd_ = std::move(fd);
64208     }
64209 #endif
64210     if (!frame_deserializer_.EndReceive(rsize)) {
64211       // The endpoint tried to send a frame that is way too large.
64212       return sock_->Shutdown(true);  // In turn will trigger an OnDisconnect().
64213       // TODO(fmayer): check this.
64214     }
64215   } while (rsize > 0);
64216 
64217   while (std::unique_ptr<Frame> frame = frame_deserializer_.PopNextFrame())
64218     OnFrameReceived(*frame);
64219 }
64220 
OnFrameReceived(const Frame & frame)64221 void ClientImpl::OnFrameReceived(const Frame& frame) {
64222   auto queued_requests_it = queued_requests_.find(frame.request_id());
64223   if (queued_requests_it == queued_requests_.end()) {
64224     PERFETTO_DLOG("OnFrameReceived(): got invalid request_id=%" PRIu64,
64225                   static_cast<uint64_t>(frame.request_id()));
64226     return;
64227   }
64228   QueuedRequest req = std::move(queued_requests_it->second);
64229   queued_requests_.erase(queued_requests_it);
64230 
64231   if (req.type == Frame::kMsgBindServiceFieldNumber &&
64232       frame.has_msg_bind_service_reply()) {
64233     return OnBindServiceReply(std::move(req), frame.msg_bind_service_reply());
64234   }
64235   if (req.type == Frame::kMsgInvokeMethodFieldNumber &&
64236       frame.has_msg_invoke_method_reply()) {
64237     return OnInvokeMethodReply(std::move(req), frame.msg_invoke_method_reply());
64238   }
64239   if (frame.has_msg_request_error()) {
64240     PERFETTO_DLOG("Host error: %s", frame.msg_request_error().error().c_str());
64241     return;
64242   }
64243 
64244   PERFETTO_DLOG(
64245       "OnFrameReceived() request type=%d, received unknown frame in reply to "
64246       "request_id=%" PRIu64,
64247       req.type, static_cast<uint64_t>(frame.request_id()));
64248 }
64249 
OnBindServiceReply(QueuedRequest req,const Frame::BindServiceReply & reply)64250 void ClientImpl::OnBindServiceReply(QueuedRequest req,
64251                                     const Frame::BindServiceReply& reply) {
64252   base::WeakPtr<ServiceProxy>& service_proxy = req.service_proxy;
64253   if (!service_proxy)
64254     return;
64255   const char* svc_name = service_proxy->GetDescriptor().service_name;
64256   if (!reply.success()) {
64257     PERFETTO_DLOG("BindService(): unknown service_name=\"%s\"", svc_name);
64258     return service_proxy->OnConnect(false /* success */);
64259   }
64260 
64261   auto prev_service = service_bindings_.find(reply.service_id());
64262   if (prev_service != service_bindings_.end() && prev_service->second.get()) {
64263     PERFETTO_DLOG(
64264         "BindService(): Trying to bind service \"%s\" but another service "
64265         "named \"%s\" is already bound with the same ID.",
64266         svc_name, prev_service->second->GetDescriptor().service_name);
64267     return service_proxy->OnConnect(false /* success */);
64268   }
64269 
64270   // Build the method [name] -> [remote_id] map.
64271   std::map<std::string, MethodID> methods;
64272   for (const auto& method : reply.methods()) {
64273     if (method.name().empty() || method.id() <= 0) {
64274       PERFETTO_DLOG("OnBindServiceReply(): invalid method \"%s\" -> %" PRIu64,
64275                     method.name().c_str(), static_cast<uint64_t>(method.id()));
64276       continue;
64277     }
64278     methods[method.name()] = method.id();
64279   }
64280   service_proxy->InitializeBinding(weak_ptr_factory_.GetWeakPtr(),
64281                                    reply.service_id(), std::move(methods));
64282   service_bindings_[reply.service_id()] = service_proxy;
64283   service_proxy->OnConnect(true /* success */);
64284 }
64285 
OnInvokeMethodReply(QueuedRequest req,const Frame::InvokeMethodReply & reply)64286 void ClientImpl::OnInvokeMethodReply(QueuedRequest req,
64287                                      const Frame::InvokeMethodReply& reply) {
64288   base::WeakPtr<ServiceProxy> service_proxy = req.service_proxy;
64289   if (!service_proxy)
64290     return;
64291   std::unique_ptr<ProtoMessage> decoded_reply;
64292   if (reply.success()) {
64293     // If this becomes a hotspot, optimize by maintaining a dedicated hashtable.
64294     for (const auto& method : service_proxy->GetDescriptor().methods) {
64295       if (req.method_name == method.name) {
64296         decoded_reply = method.reply_proto_decoder(reply.reply_proto());
64297         break;
64298       }
64299     }
64300   }
64301   const RequestID request_id = req.request_id;
64302   invoking_method_reply_ = true;
64303   service_proxy->EndInvoke(request_id, std::move(decoded_reply),
64304                            reply.has_more());
64305   invoking_method_reply_ = false;
64306 
64307   // If this is a streaming method and future replies will be resolved, put back
64308   // the |req| with the callback into the set of active requests.
64309   if (reply.has_more())
64310     queued_requests_.emplace(request_id, std::move(req));
64311 }
64312 
64313 ClientImpl::QueuedRequest::QueuedRequest() = default;
64314 
TakeReceivedFD()64315 base::ScopedFile ClientImpl::TakeReceivedFD() {
64316   return std::move(received_fd_);
64317 }
64318 
64319 }  // namespace ipc
64320 }  // namespace perfetto
64321 // gen_amalgamated begin source: src/ipc/service_proxy.cc
64322 /*
64323  * Copyright (C) 2017 The Android Open Source Project
64324  *
64325  * Licensed under the Apache License, Version 2.0 (the "License");
64326  * you may not use this file except in compliance with the License.
64327  * You may obtain a copy of the License at
64328  *
64329  *      http://www.apache.org/licenses/LICENSE-2.0
64330  *
64331  * Unless required by applicable law or agreed to in writing, software
64332  * distributed under the License is distributed on an "AS IS" BASIS,
64333  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64334  * See the License for the specific language governing permissions and
64335  * limitations under the License.
64336  */
64337 
64338 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
64339 
64340 #include <utility>
64341 
64342 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
64343 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
64344 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_descriptor.h"
64345 // gen_amalgamated expanded: #include "src/ipc/client_impl.h"
64346 
64347 // gen_amalgamated expanded: #include "protos/perfetto/ipc/wire_protocol.gen.h"
64348 
64349 namespace perfetto {
64350 namespace ipc {
64351 
ServiceProxy(EventListener * event_listener)64352 ServiceProxy::ServiceProxy(EventListener* event_listener)
64353     : event_listener_(event_listener), weak_ptr_factory_(this) {}
64354 
~ServiceProxy()64355 ServiceProxy::~ServiceProxy() {
64356   if (client_ && connected())
64357     client_->UnbindService(service_id_);
64358 }
64359 
InitializeBinding(base::WeakPtr<Client> client,ServiceID service_id,std::map<std::string,MethodID> remote_method_ids)64360 void ServiceProxy::InitializeBinding(
64361     base::WeakPtr<Client> client,
64362     ServiceID service_id,
64363     std::map<std::string, MethodID> remote_method_ids) {
64364   client_ = std::move(client);
64365   service_id_ = service_id;
64366   remote_method_ids_ = std::move(remote_method_ids);
64367 }
64368 
BeginInvoke(const std::string & method_name,const ProtoMessage & request,DeferredBase reply,int fd)64369 void ServiceProxy::BeginInvoke(const std::string& method_name,
64370                                const ProtoMessage& request,
64371                                DeferredBase reply,
64372                                int fd) {
64373   // |reply| will auto-resolve if it gets out of scope early.
64374   if (!connected()) {
64375     PERFETTO_DFATAL("Not connected.");
64376     return;
64377   }
64378   if (!client_)
64379     return;  // The Client object has been destroyed in the meantime.
64380 
64381   auto remote_method_it = remote_method_ids_.find(method_name);
64382   RequestID request_id = 0;
64383   const bool drop_reply = !reply.IsBound();
64384   if (remote_method_it != remote_method_ids_.end()) {
64385     request_id =
64386         static_cast<ClientImpl*>(client_.get())
64387             ->BeginInvoke(service_id_, method_name, remote_method_it->second,
64388                           request, drop_reply, weak_ptr_factory_.GetWeakPtr(),
64389                           fd);
64390   } else {
64391     PERFETTO_DLOG("Cannot find method \"%s\" on the host", method_name.c_str());
64392   }
64393 
64394   // When passing |drop_reply| == true, the returned |request_id| should be 0.
64395   PERFETTO_DCHECK(!drop_reply || !request_id);
64396 
64397   if (!request_id)
64398     return;
64399   PERFETTO_DCHECK(pending_callbacks_.count(request_id) == 0);
64400   pending_callbacks_.emplace(request_id, std::move(reply));
64401 }
64402 
EndInvoke(RequestID request_id,std::unique_ptr<ProtoMessage> result,bool has_more)64403 void ServiceProxy::EndInvoke(RequestID request_id,
64404                              std::unique_ptr<ProtoMessage> result,
64405                              bool has_more) {
64406   auto callback_it = pending_callbacks_.find(request_id);
64407   if (callback_it == pending_callbacks_.end()) {
64408     // Either we are getting a reply for a method we never invoked, or we are
64409     // getting a reply to a method marked drop_reply (that has been invoked
64410     // without binding any callback in the Defererd response object).
64411     PERFETTO_DFATAL("Unexpected reply received.");
64412     return;
64413   }
64414   DeferredBase& reply_callback = callback_it->second;
64415   AsyncResult<ProtoMessage> reply(std::move(result), has_more);
64416   reply_callback.Resolve(std::move(reply));
64417   if (!has_more)
64418     pending_callbacks_.erase(callback_it);
64419 }
64420 
OnConnect(bool success)64421 void ServiceProxy::OnConnect(bool success) {
64422   if (success) {
64423     PERFETTO_DCHECK(service_id_);
64424     return event_listener_->OnConnect();
64425   }
64426   return event_listener_->OnDisconnect();
64427 }
64428 
OnDisconnect()64429 void ServiceProxy::OnDisconnect() {
64430   pending_callbacks_.clear();  // Will Reject() all the pending callbacks.
64431   event_listener_->OnDisconnect();
64432 }
64433 
GetWeakPtr() const64434 base::WeakPtr<ServiceProxy> ServiceProxy::GetWeakPtr() const {
64435   return weak_ptr_factory_.GetWeakPtr();
64436 }
64437 
64438 }  // namespace ipc
64439 }  // namespace perfetto
64440 // gen_amalgamated begin source: src/ipc/host_impl.cc
64441 // gen_amalgamated begin header: src/ipc/host_impl.h
64442 /*
64443  * Copyright (C) 2017 The Android Open Source Project
64444  *
64445  * Licensed under the Apache License, Version 2.0 (the "License");
64446  * you may not use this file except in compliance with the License.
64447  * You may obtain a copy of the License at
64448  *
64449  *      http://www.apache.org/licenses/LICENSE-2.0
64450  *
64451  * Unless required by applicable law or agreed to in writing, software
64452  * distributed under the License is distributed on an "AS IS" BASIS,
64453  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64454  * See the License for the specific language governing permissions and
64455  * limitations under the License.
64456  */
64457 
64458 #ifndef SRC_IPC_HOST_IMPL_H_
64459 #define SRC_IPC_HOST_IMPL_H_
64460 
64461 #include <map>
64462 #include <set>
64463 #include <string>
64464 #include <vector>
64465 
64466 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
64467 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
64468 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
64469 // gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
64470 // gen_amalgamated expanded: #include "perfetto/ext/ipc/host.h"
64471 // gen_amalgamated expanded: #include "src/ipc/buffered_frame_deserializer.h"
64472 
64473 namespace perfetto {
64474 namespace ipc {
64475 
64476 class HostImpl : public Host, public base::UnixSocket::EventListener {
64477  public:
64478   HostImpl(const char* socket_name, base::TaskRunner*);
64479   HostImpl(base::ScopedSocketHandle, base::TaskRunner*);
64480   ~HostImpl() override;
64481 
64482   // Host implementation.
64483   bool ExposeService(std::unique_ptr<Service>) override;
64484 
64485   // base::UnixSocket::EventListener implementation.
64486   void OnNewIncomingConnection(base::UnixSocket*,
64487                                std::unique_ptr<base::UnixSocket>) override;
64488   void OnDisconnect(base::UnixSocket*) override;
64489   void OnDataAvailable(base::UnixSocket*) override;
64490 
sock() const64491   const base::UnixSocket* sock() const { return sock_.get(); }
64492 
64493  private:
64494   // Owns the per-client receive buffer (BufferedFrameDeserializer).
64495   struct ClientConnection {
64496     ~ClientConnection();
64497     ClientID id;
64498     std::unique_ptr<base::UnixSocket> sock;
64499     BufferedFrameDeserializer frame_deserializer;
64500     base::ScopedFile received_fd;
64501   };
64502   struct ExposedService {
64503     ExposedService(ServiceID, const std::string&, std::unique_ptr<Service>);
64504     ~ExposedService();
64505     ExposedService(ExposedService&&) noexcept;
64506     ExposedService& operator=(ExposedService&&);
64507 
64508     ServiceID id;
64509     std::string name;
64510     std::unique_ptr<Service> instance;
64511   };
64512 
64513   HostImpl(const HostImpl&) = delete;
64514   HostImpl& operator=(const HostImpl&) = delete;
64515 
64516   bool Initialize(const char* socket_name);
64517   void OnReceivedFrame(ClientConnection*, const Frame&);
64518   void OnBindService(ClientConnection*, const Frame&);
64519   void OnInvokeMethod(ClientConnection*, const Frame&);
64520   void ReplyToMethodInvocation(ClientID, RequestID, AsyncResult<ProtoMessage>);
64521   const ExposedService* GetServiceByName(const std::string&);
64522 
64523   static void SendFrame(ClientConnection*, const Frame&, int fd = -1);
64524 
64525   base::TaskRunner* const task_runner_;
64526   std::map<ServiceID, ExposedService> services_;
64527   std::unique_ptr<base::UnixSocket> sock_;  // The listening socket.
64528   std::map<ClientID, std::unique_ptr<ClientConnection>> clients_;
64529   std::map<base::UnixSocket*, ClientConnection*> clients_by_socket_;
64530   ServiceID last_service_id_ = 0;
64531   ClientID last_client_id_ = 0;
64532   PERFETTO_THREAD_CHECKER(thread_checker_)
64533   base::WeakPtrFactory<HostImpl> weak_ptr_factory_;  // Keep last.
64534 };
64535 
64536 }  // namespace ipc
64537 }  // namespace perfetto
64538 
64539 #endif  // SRC_IPC_HOST_IMPL_H_
64540 /*
64541  * Copyright (C) 2017 The Android Open Source Project
64542  *
64543  * Licensed under the Apache License, Version 2.0 (the "License");
64544  * you may not use this file except in compliance with the License.
64545  * You may obtain a copy of the License at
64546  *
64547  *      http://www.apache.org/licenses/LICENSE-2.0
64548  *
64549  * Unless required by applicable law or agreed to in writing, software
64550  * distributed under the License is distributed on an "AS IS" BASIS,
64551  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64552  * See the License for the specific language governing permissions and
64553  * limitations under the License.
64554  */
64555 
64556 // gen_amalgamated expanded: #include "src/ipc/host_impl.h"
64557 
64558 #include <inttypes.h>
64559 
64560 #include <algorithm>
64561 #include <utility>
64562 
64563 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
64564 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
64565 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
64566 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_descriptor.h"
64567 
64568 // gen_amalgamated expanded: #include "protos/perfetto/ipc/wire_protocol.gen.h"
64569 
64570 // TODO(primiano): put limits on #connections/uid and req. queue (b/69093705).
64571 
64572 namespace perfetto {
64573 namespace ipc {
64574 
64575 namespace {
64576 
64577 constexpr base::SockFamily kHostSockFamily =
64578     kUseTCPSocket ? base::SockFamily::kInet : base::SockFamily::kUnix;
64579 
GetPosixPeerUid(base::UnixSocket * sock)64580 uid_t GetPosixPeerUid(base::UnixSocket* sock) {
64581 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
64582   base::ignore_result(sock);
64583   // Unsupported. Must be != kInvalidUid or the PacketValidator will fail.
64584   return 0;
64585 #else
64586   return sock->peer_uid_posix();
64587 #endif
64588 }
64589 
64590 }  // namespace
64591 
64592 // static
CreateInstance(const char * socket_name,base::TaskRunner * task_runner)64593 std::unique_ptr<Host> Host::CreateInstance(const char* socket_name,
64594                                            base::TaskRunner* task_runner) {
64595   std::unique_ptr<HostImpl> host(new HostImpl(socket_name, task_runner));
64596   if (!host->sock() || !host->sock()->is_listening())
64597     return nullptr;
64598   return std::unique_ptr<Host>(std::move(host));
64599 }
64600 
64601 // static
CreateInstance(base::ScopedSocketHandle socket_fd,base::TaskRunner * task_runner)64602 std::unique_ptr<Host> Host::CreateInstance(base::ScopedSocketHandle socket_fd,
64603                                            base::TaskRunner* task_runner) {
64604   std::unique_ptr<HostImpl> host(
64605       new HostImpl(std::move(socket_fd), task_runner));
64606   if (!host->sock() || !host->sock()->is_listening())
64607     return nullptr;
64608   return std::unique_ptr<Host>(std::move(host));
64609 }
64610 
HostImpl(base::ScopedSocketHandle socket_fd,base::TaskRunner * task_runner)64611 HostImpl::HostImpl(base::ScopedSocketHandle socket_fd,
64612                    base::TaskRunner* task_runner)
64613     : task_runner_(task_runner), weak_ptr_factory_(this) {
64614   PERFETTO_DCHECK_THREAD(thread_checker_);
64615   sock_ = base::UnixSocket::Listen(std::move(socket_fd), this, task_runner_,
64616                                    kHostSockFamily, base::SockType::kStream);
64617 }
64618 
HostImpl(const char * socket_name,base::TaskRunner * task_runner)64619 HostImpl::HostImpl(const char* socket_name, base::TaskRunner* task_runner)
64620     : task_runner_(task_runner), weak_ptr_factory_(this) {
64621   PERFETTO_DCHECK_THREAD(thread_checker_);
64622   sock_ = base::UnixSocket::Listen(socket_name, this, task_runner_,
64623                                    kHostSockFamily, base::SockType::kStream);
64624   if (!sock_) {
64625     PERFETTO_PLOG("Failed to create %s", socket_name);
64626   }
64627 }
64628 
64629 HostImpl::~HostImpl() = default;
64630 
ExposeService(std::unique_ptr<Service> service)64631 bool HostImpl::ExposeService(std::unique_ptr<Service> service) {
64632   PERFETTO_DCHECK_THREAD(thread_checker_);
64633   const std::string& service_name = service->GetDescriptor().service_name;
64634   if (GetServiceByName(service_name)) {
64635     PERFETTO_DLOG("Duplicate ExposeService(): %s", service_name.c_str());
64636     return false;
64637   }
64638   ServiceID sid = ++last_service_id_;
64639   ExposedService exposed_service(sid, service_name, std::move(service));
64640   services_.emplace(sid, std::move(exposed_service));
64641   return true;
64642 }
64643 
OnNewIncomingConnection(base::UnixSocket *,std::unique_ptr<base::UnixSocket> new_conn)64644 void HostImpl::OnNewIncomingConnection(
64645     base::UnixSocket*,
64646     std::unique_ptr<base::UnixSocket> new_conn) {
64647   PERFETTO_DCHECK_THREAD(thread_checker_);
64648   std::unique_ptr<ClientConnection> client(new ClientConnection());
64649   ClientID client_id = ++last_client_id_;
64650   clients_by_socket_[new_conn.get()] = client.get();
64651   client->id = client_id;
64652   client->sock = std::move(new_conn);
64653   // Watchdog is 30 seconds, so set the socket timeout to 10 seconds.
64654   client->sock->SetTxTimeout(10000);
64655   clients_[client_id] = std::move(client);
64656 }
64657 
OnDataAvailable(base::UnixSocket * sock)64658 void HostImpl::OnDataAvailable(base::UnixSocket* sock) {
64659   PERFETTO_DCHECK_THREAD(thread_checker_);
64660   auto it = clients_by_socket_.find(sock);
64661   if (it == clients_by_socket_.end())
64662     return;
64663   ClientConnection* client = it->second;
64664   BufferedFrameDeserializer& frame_deserializer = client->frame_deserializer;
64665 
64666   size_t rsize;
64667   do {
64668     auto buf = frame_deserializer.BeginReceive();
64669     base::ScopedFile fd;
64670     rsize = client->sock->Receive(buf.data, buf.size, &fd);
64671     if (fd) {
64672       PERFETTO_DCHECK(!client->received_fd);
64673       client->received_fd = std::move(fd);
64674     }
64675     if (!frame_deserializer.EndReceive(rsize))
64676       return OnDisconnect(client->sock.get());
64677   } while (rsize > 0);
64678 
64679   for (;;) {
64680     std::unique_ptr<Frame> frame = frame_deserializer.PopNextFrame();
64681     if (!frame)
64682       break;
64683     OnReceivedFrame(client, *frame);
64684   }
64685 }
64686 
OnReceivedFrame(ClientConnection * client,const Frame & req_frame)64687 void HostImpl::OnReceivedFrame(ClientConnection* client,
64688                                const Frame& req_frame) {
64689   if (req_frame.has_msg_bind_service())
64690     return OnBindService(client, req_frame);
64691   if (req_frame.has_msg_invoke_method())
64692     return OnInvokeMethod(client, req_frame);
64693 
64694   PERFETTO_DLOG("Received invalid RPC frame from client %" PRIu64, client->id);
64695   Frame reply_frame;
64696   reply_frame.set_request_id(req_frame.request_id());
64697   reply_frame.mutable_msg_request_error()->set_error("unknown request");
64698   SendFrame(client, reply_frame);
64699 }
64700 
OnBindService(ClientConnection * client,const Frame & req_frame)64701 void HostImpl::OnBindService(ClientConnection* client, const Frame& req_frame) {
64702   // Binding a service doesn't do anything major. It just returns back the
64703   // service id and its method map.
64704   const Frame::BindService& req = req_frame.msg_bind_service();
64705   Frame reply_frame;
64706   reply_frame.set_request_id(req_frame.request_id());
64707   auto* reply = reply_frame.mutable_msg_bind_service_reply();
64708   const ExposedService* service = GetServiceByName(req.service_name());
64709   if (service) {
64710     reply->set_success(true);
64711     reply->set_service_id(service->id);
64712     uint32_t method_id = 1;  // method ids start at index 1.
64713     for (const auto& desc_method : service->instance->GetDescriptor().methods) {
64714       Frame::BindServiceReply::MethodInfo* method_info = reply->add_methods();
64715       method_info->set_name(desc_method.name);
64716       method_info->set_id(method_id++);
64717     }
64718   }
64719   SendFrame(client, reply_frame);
64720 }
64721 
OnInvokeMethod(ClientConnection * client,const Frame & req_frame)64722 void HostImpl::OnInvokeMethod(ClientConnection* client,
64723                               const Frame& req_frame) {
64724   const Frame::InvokeMethod& req = req_frame.msg_invoke_method();
64725   Frame reply_frame;
64726   RequestID request_id = req_frame.request_id();
64727   reply_frame.set_request_id(request_id);
64728   reply_frame.mutable_msg_invoke_method_reply()->set_success(false);
64729   auto svc_it = services_.find(req.service_id());
64730   if (svc_it == services_.end())
64731     return SendFrame(client, reply_frame);  // |success| == false by default.
64732 
64733   Service* service = svc_it->second.instance.get();
64734   const ServiceDescriptor& svc = service->GetDescriptor();
64735   const auto& methods = svc.methods;
64736   const uint32_t method_id = req.method_id();
64737   if (method_id == 0 || method_id > methods.size())
64738     return SendFrame(client, reply_frame);
64739 
64740   const ServiceDescriptor::Method& method = methods[method_id - 1];
64741   std::unique_ptr<ProtoMessage> decoded_req_args(
64742       method.request_proto_decoder(req.args_proto()));
64743   if (!decoded_req_args)
64744     return SendFrame(client, reply_frame);
64745 
64746   Deferred<ProtoMessage> deferred_reply;
64747   base::WeakPtr<HostImpl> host_weak_ptr = weak_ptr_factory_.GetWeakPtr();
64748   ClientID client_id = client->id;
64749 
64750   if (!req.drop_reply()) {
64751     deferred_reply.Bind([host_weak_ptr, client_id,
64752                          request_id](AsyncResult<ProtoMessage> reply) {
64753       if (!host_weak_ptr)
64754         return;  // The reply came too late, the HostImpl has gone.
64755       host_weak_ptr->ReplyToMethodInvocation(client_id, request_id,
64756                                              std::move(reply));
64757     });
64758   }
64759 
64760   service->client_info_ =
64761       ClientInfo(client->id, GetPosixPeerUid(client->sock.get()));
64762   service->received_fd_ = &client->received_fd;
64763   method.invoker(service, *decoded_req_args, std::move(deferred_reply));
64764   service->received_fd_ = nullptr;
64765   service->client_info_ = ClientInfo();
64766 }
64767 
ReplyToMethodInvocation(ClientID client_id,RequestID request_id,AsyncResult<ProtoMessage> reply)64768 void HostImpl::ReplyToMethodInvocation(ClientID client_id,
64769                                        RequestID request_id,
64770                                        AsyncResult<ProtoMessage> reply) {
64771   auto client_iter = clients_.find(client_id);
64772   if (client_iter == clients_.end())
64773     return;  // client has disconnected by the time we got the async reply.
64774 
64775   ClientConnection* client = client_iter->second.get();
64776   Frame reply_frame;
64777   reply_frame.set_request_id(request_id);
64778 
64779   // TODO(fmayer): add a test to guarantee that the reply is consumed within the
64780   // same call stack and not kept around. ConsumerIPCService::OnTraceData()
64781   // relies on this behavior.
64782   auto* reply_frame_data = reply_frame.mutable_msg_invoke_method_reply();
64783   reply_frame_data->set_has_more(reply.has_more());
64784   if (reply.success()) {
64785     std::string reply_proto = reply->SerializeAsString();
64786     reply_frame_data->set_reply_proto(reply_proto);
64787     reply_frame_data->set_success(true);
64788   }
64789   SendFrame(client, reply_frame, reply.fd());
64790 }
64791 
64792 // static
SendFrame(ClientConnection * client,const Frame & frame,int fd)64793 void HostImpl::SendFrame(ClientConnection* client, const Frame& frame, int fd) {
64794   std::string buf = BufferedFrameDeserializer::Serialize(frame);
64795 
64796   // When a new Client connects in OnNewClientConnection we set a timeout on
64797   // Send (see call to SetTxTimeout).
64798   //
64799   // The old behaviour was to do a blocking I/O call, which caused crashes from
64800   // misbehaving producers (see b/169051440).
64801   bool res = client->sock->Send(buf.data(), buf.size(), fd);
64802   // If we timeout |res| will be false, but the UnixSocket will have called
64803   // UnixSocket::ShutDown() and thus |is_connected()| is false.
64804   PERFETTO_CHECK(res || !client->sock->is_connected());
64805 }
64806 
OnDisconnect(base::UnixSocket * sock)64807 void HostImpl::OnDisconnect(base::UnixSocket* sock) {
64808   PERFETTO_DCHECK_THREAD(thread_checker_);
64809   auto it = clients_by_socket_.find(sock);
64810   if (it == clients_by_socket_.end())
64811     return;
64812   ClientID client_id = it->second->id;
64813 
64814   ClientInfo client_info(client_id, GetPosixPeerUid(sock));
64815   clients_by_socket_.erase(it);
64816   PERFETTO_DCHECK(clients_.count(client_id));
64817   clients_.erase(client_id);
64818 
64819   for (const auto& service_it : services_) {
64820     Service& service = *service_it.second.instance;
64821     service.client_info_ = client_info;
64822     service.OnClientDisconnected();
64823     service.client_info_ = ClientInfo();
64824   }
64825 }
64826 
GetServiceByName(const std::string & name)64827 const HostImpl::ExposedService* HostImpl::GetServiceByName(
64828     const std::string& name) {
64829   // This could be optimized by using another map<name,ServiceID>. However this
64830   // is used only by Bind/ExposeService that are quite rare (once per client
64831   // connection and once per service instance), not worth it.
64832   for (const auto& it : services_) {
64833     if (it.second.name == name)
64834       return &it.second;
64835   }
64836   return nullptr;
64837 }
64838 
ExposedService(ServiceID id_,const std::string & name_,std::unique_ptr<Service> instance_)64839 HostImpl::ExposedService::ExposedService(ServiceID id_,
64840                                          const std::string& name_,
64841                                          std::unique_ptr<Service> instance_)
64842     : id(id_), name(name_), instance(std::move(instance_)) {}
64843 
64844 HostImpl::ExposedService::ExposedService(ExposedService&&) noexcept = default;
64845 HostImpl::ExposedService& HostImpl::ExposedService::operator=(
64846     HostImpl::ExposedService&&) = default;
64847 HostImpl::ExposedService::~ExposedService() = default;
64848 
64849 HostImpl::ClientConnection::~ClientConnection() = default;
64850 
64851 }  // namespace ipc
64852 }  // namespace perfetto
64853 // gen_amalgamated begin source: gen/protos/perfetto/ipc/consumer_port.ipc.cc
64854 // gen_amalgamated begin header: gen/protos/perfetto/ipc/consumer_port.ipc.h
64855 // DO NOT EDIT. Autogenerated by Perfetto IPC
64856 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_CONSUMER_PORT_PROTO_H_
64857 #define PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_CONSUMER_PORT_PROTO_H_
64858 
64859 // gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
64860 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
64861 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_descriptor.h"
64862 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
64863 
64864 // gen_amalgamated expanded: #include "protos/perfetto/ipc/consumer_port.gen.h"
64865 // gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"
64866 // gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_state.gen.h"
64867 // gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_capabilities.gen.h"
64868 // gen_amalgamated expanded: #include "protos/perfetto/common/trace_stats.gen.h"
64869 // gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.gen.h"
64870 
64871 namespace perfetto {
64872 namespace protos {
64873 namespace gen {
64874 
64875 class ConsumerPort : public ::perfetto::ipc::Service {
64876  private:
64877   static ::perfetto::ipc::ServiceDescriptor* NewDescriptor();
64878 
64879  public:
64880   ~ConsumerPort() override;
64881 
64882   static const ::perfetto::ipc::ServiceDescriptor& GetDescriptorStatic();
64883 
64884   // Service implementation.
64885   const ::perfetto::ipc::ServiceDescriptor& GetDescriptor() override;
64886 
64887   // Methods from the .proto file
64888   using DeferredEnableTracingResponse = ::perfetto::ipc::Deferred<EnableTracingResponse>;
64889   virtual void EnableTracing(const EnableTracingRequest&, DeferredEnableTracingResponse) = 0;
64890 
64891   using DeferredDisableTracingResponse = ::perfetto::ipc::Deferred<DisableTracingResponse>;
64892   virtual void DisableTracing(const DisableTracingRequest&, DeferredDisableTracingResponse) = 0;
64893 
64894   using DeferredReadBuffersResponse = ::perfetto::ipc::Deferred<ReadBuffersResponse>;
64895   virtual void ReadBuffers(const ReadBuffersRequest&, DeferredReadBuffersResponse) = 0;
64896 
64897   using DeferredFreeBuffersResponse = ::perfetto::ipc::Deferred<FreeBuffersResponse>;
64898   virtual void FreeBuffers(const FreeBuffersRequest&, DeferredFreeBuffersResponse) = 0;
64899 
64900   using DeferredFlushResponse = ::perfetto::ipc::Deferred<FlushResponse>;
64901   virtual void Flush(const FlushRequest&, DeferredFlushResponse) = 0;
64902 
64903   using DeferredStartTracingResponse = ::perfetto::ipc::Deferred<StartTracingResponse>;
64904   virtual void StartTracing(const StartTracingRequest&, DeferredStartTracingResponse) = 0;
64905 
64906   using DeferredChangeTraceConfigResponse = ::perfetto::ipc::Deferred<ChangeTraceConfigResponse>;
64907   virtual void ChangeTraceConfig(const ChangeTraceConfigRequest&, DeferredChangeTraceConfigResponse) = 0;
64908 
64909   using DeferredDetachResponse = ::perfetto::ipc::Deferred<DetachResponse>;
64910   virtual void Detach(const DetachRequest&, DeferredDetachResponse) = 0;
64911 
64912   using DeferredAttachResponse = ::perfetto::ipc::Deferred<AttachResponse>;
64913   virtual void Attach(const AttachRequest&, DeferredAttachResponse) = 0;
64914 
64915   using DeferredGetTraceStatsResponse = ::perfetto::ipc::Deferred<GetTraceStatsResponse>;
64916   virtual void GetTraceStats(const GetTraceStatsRequest&, DeferredGetTraceStatsResponse) = 0;
64917 
64918   using DeferredObserveEventsResponse = ::perfetto::ipc::Deferred<ObserveEventsResponse>;
64919   virtual void ObserveEvents(const ObserveEventsRequest&, DeferredObserveEventsResponse) = 0;
64920 
64921   using DeferredQueryServiceStateResponse = ::perfetto::ipc::Deferred<QueryServiceStateResponse>;
64922   virtual void QueryServiceState(const QueryServiceStateRequest&, DeferredQueryServiceStateResponse) = 0;
64923 
64924   using DeferredQueryCapabilitiesResponse = ::perfetto::ipc::Deferred<QueryCapabilitiesResponse>;
64925   virtual void QueryCapabilities(const QueryCapabilitiesRequest&, DeferredQueryCapabilitiesResponse) = 0;
64926 
64927   using DeferredSaveTraceForBugreportResponse = ::perfetto::ipc::Deferred<SaveTraceForBugreportResponse>;
64928   virtual void SaveTraceForBugreport(const SaveTraceForBugreportRequest&, DeferredSaveTraceForBugreportResponse) = 0;
64929 
64930 };
64931 
64932 
64933 class ConsumerPortProxy : public ::perfetto::ipc::ServiceProxy {
64934  public:
64935    explicit ConsumerPortProxy(::perfetto::ipc::ServiceProxy::EventListener*);
64936    ~ConsumerPortProxy() override;
64937 
64938   // ServiceProxy implementation.
64939   const ::perfetto::ipc::ServiceDescriptor& GetDescriptor() override;
64940 
64941   // Methods from the .proto file
64942   using DeferredEnableTracingResponse = ::perfetto::ipc::Deferred<EnableTracingResponse>;
64943   void EnableTracing(const EnableTracingRequest&, DeferredEnableTracingResponse, int fd = -1);
64944 
64945   using DeferredDisableTracingResponse = ::perfetto::ipc::Deferred<DisableTracingResponse>;
64946   void DisableTracing(const DisableTracingRequest&, DeferredDisableTracingResponse, int fd = -1);
64947 
64948   using DeferredReadBuffersResponse = ::perfetto::ipc::Deferred<ReadBuffersResponse>;
64949   void ReadBuffers(const ReadBuffersRequest&, DeferredReadBuffersResponse, int fd = -1);
64950 
64951   using DeferredFreeBuffersResponse = ::perfetto::ipc::Deferred<FreeBuffersResponse>;
64952   void FreeBuffers(const FreeBuffersRequest&, DeferredFreeBuffersResponse, int fd = -1);
64953 
64954   using DeferredFlushResponse = ::perfetto::ipc::Deferred<FlushResponse>;
64955   void Flush(const FlushRequest&, DeferredFlushResponse, int fd = -1);
64956 
64957   using DeferredStartTracingResponse = ::perfetto::ipc::Deferred<StartTracingResponse>;
64958   void StartTracing(const StartTracingRequest&, DeferredStartTracingResponse, int fd = -1);
64959 
64960   using DeferredChangeTraceConfigResponse = ::perfetto::ipc::Deferred<ChangeTraceConfigResponse>;
64961   void ChangeTraceConfig(const ChangeTraceConfigRequest&, DeferredChangeTraceConfigResponse, int fd = -1);
64962 
64963   using DeferredDetachResponse = ::perfetto::ipc::Deferred<DetachResponse>;
64964   void Detach(const DetachRequest&, DeferredDetachResponse, int fd = -1);
64965 
64966   using DeferredAttachResponse = ::perfetto::ipc::Deferred<AttachResponse>;
64967   void Attach(const AttachRequest&, DeferredAttachResponse, int fd = -1);
64968 
64969   using DeferredGetTraceStatsResponse = ::perfetto::ipc::Deferred<GetTraceStatsResponse>;
64970   void GetTraceStats(const GetTraceStatsRequest&, DeferredGetTraceStatsResponse, int fd = -1);
64971 
64972   using DeferredObserveEventsResponse = ::perfetto::ipc::Deferred<ObserveEventsResponse>;
64973   void ObserveEvents(const ObserveEventsRequest&, DeferredObserveEventsResponse, int fd = -1);
64974 
64975   using DeferredQueryServiceStateResponse = ::perfetto::ipc::Deferred<QueryServiceStateResponse>;
64976   void QueryServiceState(const QueryServiceStateRequest&, DeferredQueryServiceStateResponse, int fd = -1);
64977 
64978   using DeferredQueryCapabilitiesResponse = ::perfetto::ipc::Deferred<QueryCapabilitiesResponse>;
64979   void QueryCapabilities(const QueryCapabilitiesRequest&, DeferredQueryCapabilitiesResponse, int fd = -1);
64980 
64981   using DeferredSaveTraceForBugreportResponse = ::perfetto::ipc::Deferred<SaveTraceForBugreportResponse>;
64982   void SaveTraceForBugreport(const SaveTraceForBugreportRequest&, DeferredSaveTraceForBugreportResponse, int fd = -1);
64983 
64984 };
64985 
64986 }  // namespace perfetto
64987 }  // namespace protos
64988 }  // namespace gen
64989 
64990 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_CONSUMER_PORT_PROTO_H_
64991 // gen_amalgamated begin header: include/perfetto/ext/ipc/codegen_helpers.h
64992 /*
64993  * Copyright (C) 2017 The Android Open Source Project
64994  *
64995  * Licensed under the Apache License, Version 2.0 (the "License");
64996  * you may not use this file except in compliance with the License.
64997  * You may obtain a copy of the License at
64998  *
64999  *      http://www.apache.org/licenses/LICENSE-2.0
65000  *
65001  * Unless required by applicable law or agreed to in writing, software
65002  * distributed under the License is distributed on an "AS IS" BASIS,
65003  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65004  * See the License for the specific language governing permissions and
65005  * limitations under the License.
65006  */
65007 
65008 // This file is only meant to be included in autogenerated .cc files.
65009 
65010 #ifndef INCLUDE_PERFETTO_EXT_IPC_CODEGEN_HELPERS_H_
65011 #define INCLUDE_PERFETTO_EXT_IPC_CODEGEN_HELPERS_H_
65012 
65013 #include <memory>
65014 
65015 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
65016 // gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
65017 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
65018 
65019 // A templated protobuf message decoder. Returns nullptr in case of failure.
65020 template <typename T>
_IPC_Decoder(const std::string & proto_data)65021 ::std::unique_ptr<::perfetto::ipc::ProtoMessage> _IPC_Decoder(
65022     const std::string& proto_data) {
65023   ::std::unique_ptr<::perfetto::ipc::ProtoMessage> msg(new T());
65024   if (msg->ParseFromString(proto_data))
65025     return msg;
65026   return nullptr;
65027 }
65028 
65029 // Templated method dispatcher. Used to obtain a function pointer to a given
65030 // IPC method (Method) of a given service (TSvc) that can be invoked by the
65031 // host-side machinery starting from a generic Service pointer and a generic
65032 // ProtoMessage request argument.
65033 template <typename TSvc,    // Type of the actual Service subclass.
65034           typename TReq,    // Type of the request argument.
65035           typename TReply,  // Type of the reply argument.
65036           void (TSvc::*Method)(const TReq&, ::perfetto::ipc::Deferred<TReply>)>
_IPC_Invoker(::perfetto::ipc::Service * s,const::perfetto::ipc::ProtoMessage & req,::perfetto::ipc::DeferredBase reply)65037 void _IPC_Invoker(::perfetto::ipc::Service* s,
65038                   const ::perfetto::ipc::ProtoMessage& req,
65039                   ::perfetto::ipc::DeferredBase reply) {
65040   (*static_cast<TSvc*>(s).*Method)(
65041       static_cast<const TReq&>(req),
65042       ::perfetto::ipc::Deferred<TReply>(::std::move(reply)));
65043 }
65044 
65045 #endif  // INCLUDE_PERFETTO_EXT_IPC_CODEGEN_HELPERS_H_
65046 // DO NOT EDIT. Autogenerated by Perfetto IPC
65047 // gen_amalgamated expanded: #include "protos/perfetto/ipc/consumer_port.ipc.h"
65048 // gen_amalgamated expanded: #include "perfetto/ext/ipc/codegen_helpers.h"
65049 
65050 #include <memory>
65051 
65052 namespace perfetto {
65053 namespace protos {
65054 namespace gen {
NewDescriptor()65055 ::perfetto::ipc::ServiceDescriptor* ConsumerPort::NewDescriptor() {
65056   auto* desc = new ::perfetto::ipc::ServiceDescriptor();
65057   desc->service_name = "ConsumerPort";
65058 
65059   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
65060      "EnableTracing",
65061      &_IPC_Decoder<EnableTracingRequest>,
65062      &_IPC_Decoder<EnableTracingResponse>,
65063      &_IPC_Invoker<ConsumerPort, EnableTracingRequest, EnableTracingResponse, &ConsumerPort::EnableTracing>});
65064 
65065   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
65066      "DisableTracing",
65067      &_IPC_Decoder<DisableTracingRequest>,
65068      &_IPC_Decoder<DisableTracingResponse>,
65069      &_IPC_Invoker<ConsumerPort, DisableTracingRequest, DisableTracingResponse, &ConsumerPort::DisableTracing>});
65070 
65071   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
65072      "ReadBuffers",
65073      &_IPC_Decoder<ReadBuffersRequest>,
65074      &_IPC_Decoder<ReadBuffersResponse>,
65075      &_IPC_Invoker<ConsumerPort, ReadBuffersRequest, ReadBuffersResponse, &ConsumerPort::ReadBuffers>});
65076 
65077   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
65078      "FreeBuffers",
65079      &_IPC_Decoder<FreeBuffersRequest>,
65080      &_IPC_Decoder<FreeBuffersResponse>,
65081      &_IPC_Invoker<ConsumerPort, FreeBuffersRequest, FreeBuffersResponse, &ConsumerPort::FreeBuffers>});
65082 
65083   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
65084      "Flush",
65085      &_IPC_Decoder<FlushRequest>,
65086      &_IPC_Decoder<FlushResponse>,
65087      &_IPC_Invoker<ConsumerPort, FlushRequest, FlushResponse, &ConsumerPort::Flush>});
65088 
65089   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
65090      "StartTracing",
65091      &_IPC_Decoder<StartTracingRequest>,
65092      &_IPC_Decoder<StartTracingResponse>,
65093      &_IPC_Invoker<ConsumerPort, StartTracingRequest, StartTracingResponse, &ConsumerPort::StartTracing>});
65094 
65095   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
65096      "ChangeTraceConfig",
65097      &_IPC_Decoder<ChangeTraceConfigRequest>,
65098      &_IPC_Decoder<ChangeTraceConfigResponse>,
65099      &_IPC_Invoker<ConsumerPort, ChangeTraceConfigRequest, ChangeTraceConfigResponse, &ConsumerPort::ChangeTraceConfig>});
65100 
65101   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
65102      "Detach",
65103      &_IPC_Decoder<DetachRequest>,
65104      &_IPC_Decoder<DetachResponse>,
65105      &_IPC_Invoker<ConsumerPort, DetachRequest, DetachResponse, &ConsumerPort::Detach>});
65106 
65107   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
65108      "Attach",
65109      &_IPC_Decoder<AttachRequest>,
65110      &_IPC_Decoder<AttachResponse>,
65111      &_IPC_Invoker<ConsumerPort, AttachRequest, AttachResponse, &ConsumerPort::Attach>});
65112 
65113   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
65114      "GetTraceStats",
65115      &_IPC_Decoder<GetTraceStatsRequest>,
65116      &_IPC_Decoder<GetTraceStatsResponse>,
65117      &_IPC_Invoker<ConsumerPort, GetTraceStatsRequest, GetTraceStatsResponse, &ConsumerPort::GetTraceStats>});
65118 
65119   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
65120      "ObserveEvents",
65121      &_IPC_Decoder<ObserveEventsRequest>,
65122      &_IPC_Decoder<ObserveEventsResponse>,
65123      &_IPC_Invoker<ConsumerPort, ObserveEventsRequest, ObserveEventsResponse, &ConsumerPort::ObserveEvents>});
65124 
65125   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
65126      "QueryServiceState",
65127      &_IPC_Decoder<QueryServiceStateRequest>,
65128      &_IPC_Decoder<QueryServiceStateResponse>,
65129      &_IPC_Invoker<ConsumerPort, QueryServiceStateRequest, QueryServiceStateResponse, &ConsumerPort::QueryServiceState>});
65130 
65131   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
65132      "QueryCapabilities",
65133      &_IPC_Decoder<QueryCapabilitiesRequest>,
65134      &_IPC_Decoder<QueryCapabilitiesResponse>,
65135      &_IPC_Invoker<ConsumerPort, QueryCapabilitiesRequest, QueryCapabilitiesResponse, &ConsumerPort::QueryCapabilities>});
65136 
65137   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
65138      "SaveTraceForBugreport",
65139      &_IPC_Decoder<SaveTraceForBugreportRequest>,
65140      &_IPC_Decoder<SaveTraceForBugreportResponse>,
65141      &_IPC_Invoker<ConsumerPort, SaveTraceForBugreportRequest, SaveTraceForBugreportResponse, &ConsumerPort::SaveTraceForBugreport>});
65142   desc->methods.shrink_to_fit();
65143   return desc;
65144 }
65145 
65146 
GetDescriptorStatic()65147 const ::perfetto::ipc::ServiceDescriptor& ConsumerPort::GetDescriptorStatic() {
65148   static auto* instance = NewDescriptor();
65149   return *instance;
65150 }
65151 
65152 // Host-side definitions.
65153 ConsumerPort::~ConsumerPort() = default;
65154 
GetDescriptor()65155 const ::perfetto::ipc::ServiceDescriptor& ConsumerPort::GetDescriptor() {
65156   return GetDescriptorStatic();
65157 }
65158 
65159 // Client-side definitions.
ConsumerPortProxy(::perfetto::ipc::ServiceProxy::EventListener * event_listener)65160 ConsumerPortProxy::ConsumerPortProxy(::perfetto::ipc::ServiceProxy::EventListener* event_listener)
65161     : ::perfetto::ipc::ServiceProxy(event_listener) {}
65162 
65163 ConsumerPortProxy::~ConsumerPortProxy() = default;
65164 
GetDescriptor()65165 const ::perfetto::ipc::ServiceDescriptor& ConsumerPortProxy::GetDescriptor() {
65166   return ConsumerPort::GetDescriptorStatic();
65167 }
65168 
EnableTracing(const EnableTracingRequest & request,DeferredEnableTracingResponse reply,int fd)65169 void ConsumerPortProxy::EnableTracing(const EnableTracingRequest& request, DeferredEnableTracingResponse reply, int fd) {
65170   BeginInvoke("EnableTracing", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
65171               fd);
65172 }
65173 
DisableTracing(const DisableTracingRequest & request,DeferredDisableTracingResponse reply,int fd)65174 void ConsumerPortProxy::DisableTracing(const DisableTracingRequest& request, DeferredDisableTracingResponse reply, int fd) {
65175   BeginInvoke("DisableTracing", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
65176               fd);
65177 }
65178 
ReadBuffers(const ReadBuffersRequest & request,DeferredReadBuffersResponse reply,int fd)65179 void ConsumerPortProxy::ReadBuffers(const ReadBuffersRequest& request, DeferredReadBuffersResponse reply, int fd) {
65180   BeginInvoke("ReadBuffers", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
65181               fd);
65182 }
65183 
FreeBuffers(const FreeBuffersRequest & request,DeferredFreeBuffersResponse reply,int fd)65184 void ConsumerPortProxy::FreeBuffers(const FreeBuffersRequest& request, DeferredFreeBuffersResponse reply, int fd) {
65185   BeginInvoke("FreeBuffers", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
65186               fd);
65187 }
65188 
Flush(const FlushRequest & request,DeferredFlushResponse reply,int fd)65189 void ConsumerPortProxy::Flush(const FlushRequest& request, DeferredFlushResponse reply, int fd) {
65190   BeginInvoke("Flush", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
65191               fd);
65192 }
65193 
StartTracing(const StartTracingRequest & request,DeferredStartTracingResponse reply,int fd)65194 void ConsumerPortProxy::StartTracing(const StartTracingRequest& request, DeferredStartTracingResponse reply, int fd) {
65195   BeginInvoke("StartTracing", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
65196               fd);
65197 }
65198 
ChangeTraceConfig(const ChangeTraceConfigRequest & request,DeferredChangeTraceConfigResponse reply,int fd)65199 void ConsumerPortProxy::ChangeTraceConfig(const ChangeTraceConfigRequest& request, DeferredChangeTraceConfigResponse reply, int fd) {
65200   BeginInvoke("ChangeTraceConfig", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
65201               fd);
65202 }
65203 
Detach(const DetachRequest & request,DeferredDetachResponse reply,int fd)65204 void ConsumerPortProxy::Detach(const DetachRequest& request, DeferredDetachResponse reply, int fd) {
65205   BeginInvoke("Detach", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
65206               fd);
65207 }
65208 
Attach(const AttachRequest & request,DeferredAttachResponse reply,int fd)65209 void ConsumerPortProxy::Attach(const AttachRequest& request, DeferredAttachResponse reply, int fd) {
65210   BeginInvoke("Attach", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
65211               fd);
65212 }
65213 
GetTraceStats(const GetTraceStatsRequest & request,DeferredGetTraceStatsResponse reply,int fd)65214 void ConsumerPortProxy::GetTraceStats(const GetTraceStatsRequest& request, DeferredGetTraceStatsResponse reply, int fd) {
65215   BeginInvoke("GetTraceStats", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
65216               fd);
65217 }
65218 
ObserveEvents(const ObserveEventsRequest & request,DeferredObserveEventsResponse reply,int fd)65219 void ConsumerPortProxy::ObserveEvents(const ObserveEventsRequest& request, DeferredObserveEventsResponse reply, int fd) {
65220   BeginInvoke("ObserveEvents", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
65221               fd);
65222 }
65223 
QueryServiceState(const QueryServiceStateRequest & request,DeferredQueryServiceStateResponse reply,int fd)65224 void ConsumerPortProxy::QueryServiceState(const QueryServiceStateRequest& request, DeferredQueryServiceStateResponse reply, int fd) {
65225   BeginInvoke("QueryServiceState", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
65226               fd);
65227 }
65228 
QueryCapabilities(const QueryCapabilitiesRequest & request,DeferredQueryCapabilitiesResponse reply,int fd)65229 void ConsumerPortProxy::QueryCapabilities(const QueryCapabilitiesRequest& request, DeferredQueryCapabilitiesResponse reply, int fd) {
65230   BeginInvoke("QueryCapabilities", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
65231               fd);
65232 }
65233 
SaveTraceForBugreport(const SaveTraceForBugreportRequest & request,DeferredSaveTraceForBugreportResponse reply,int fd)65234 void ConsumerPortProxy::SaveTraceForBugreport(const SaveTraceForBugreportRequest& request, DeferredSaveTraceForBugreportResponse reply, int fd) {
65235   BeginInvoke("SaveTraceForBugreport", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
65236               fd);
65237 }
65238 }  // namespace perfetto
65239 }  // namespace protos
65240 }  // namespace gen
65241 // gen_amalgamated begin source: gen/protos/perfetto/ipc/producer_port.ipc.cc
65242 // gen_amalgamated begin header: gen/protos/perfetto/ipc/producer_port.ipc.h
65243 // DO NOT EDIT. Autogenerated by Perfetto IPC
65244 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_PRODUCER_PORT_PROTO_H_
65245 #define PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_PRODUCER_PORT_PROTO_H_
65246 
65247 // gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
65248 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
65249 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_descriptor.h"
65250 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
65251 
65252 // gen_amalgamated expanded: #include "protos/perfetto/ipc/producer_port.gen.h"
65253 // gen_amalgamated expanded: #include "protos/perfetto/common/commit_data_request.gen.h"
65254 // gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
65255 // gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
65256 
65257 namespace perfetto {
65258 namespace protos {
65259 namespace gen {
65260 
65261 class ProducerPort : public ::perfetto::ipc::Service {
65262  private:
65263   static ::perfetto::ipc::ServiceDescriptor* NewDescriptor();
65264 
65265  public:
65266   ~ProducerPort() override;
65267 
65268   static const ::perfetto::ipc::ServiceDescriptor& GetDescriptorStatic();
65269 
65270   // Service implementation.
65271   const ::perfetto::ipc::ServiceDescriptor& GetDescriptor() override;
65272 
65273   // Methods from the .proto file
65274   using DeferredInitializeConnectionResponse = ::perfetto::ipc::Deferred<InitializeConnectionResponse>;
65275   virtual void InitializeConnection(const InitializeConnectionRequest&, DeferredInitializeConnectionResponse) = 0;
65276 
65277   using DeferredRegisterDataSourceResponse = ::perfetto::ipc::Deferred<RegisterDataSourceResponse>;
65278   virtual void RegisterDataSource(const RegisterDataSourceRequest&, DeferredRegisterDataSourceResponse) = 0;
65279 
65280   using DeferredUnregisterDataSourceResponse = ::perfetto::ipc::Deferred<UnregisterDataSourceResponse>;
65281   virtual void UnregisterDataSource(const UnregisterDataSourceRequest&, DeferredUnregisterDataSourceResponse) = 0;
65282 
65283   using DeferredCommitDataResponse = ::perfetto::ipc::Deferred<CommitDataResponse>;
65284   virtual void CommitData(const CommitDataRequest&, DeferredCommitDataResponse) = 0;
65285 
65286   using DeferredGetAsyncCommandResponse = ::perfetto::ipc::Deferred<GetAsyncCommandResponse>;
65287   virtual void GetAsyncCommand(const GetAsyncCommandRequest&, DeferredGetAsyncCommandResponse) = 0;
65288 
65289   using DeferredRegisterTraceWriterResponse = ::perfetto::ipc::Deferred<RegisterTraceWriterResponse>;
65290   virtual void RegisterTraceWriter(const RegisterTraceWriterRequest&, DeferredRegisterTraceWriterResponse) = 0;
65291 
65292   using DeferredUnregisterTraceWriterResponse = ::perfetto::ipc::Deferred<UnregisterTraceWriterResponse>;
65293   virtual void UnregisterTraceWriter(const UnregisterTraceWriterRequest&, DeferredUnregisterTraceWriterResponse) = 0;
65294 
65295   using DeferredNotifyDataSourceStartedResponse = ::perfetto::ipc::Deferred<NotifyDataSourceStartedResponse>;
65296   virtual void NotifyDataSourceStarted(const NotifyDataSourceStartedRequest&, DeferredNotifyDataSourceStartedResponse) = 0;
65297 
65298   using DeferredNotifyDataSourceStoppedResponse = ::perfetto::ipc::Deferred<NotifyDataSourceStoppedResponse>;
65299   virtual void NotifyDataSourceStopped(const NotifyDataSourceStoppedRequest&, DeferredNotifyDataSourceStoppedResponse) = 0;
65300 
65301   using DeferredActivateTriggersResponse = ::perfetto::ipc::Deferred<ActivateTriggersResponse>;
65302   virtual void ActivateTriggers(const ActivateTriggersRequest&, DeferredActivateTriggersResponse) = 0;
65303 
65304   using DeferredSyncResponse = ::perfetto::ipc::Deferred<SyncResponse>;
65305   virtual void Sync(const SyncRequest&, DeferredSyncResponse) = 0;
65306 
65307 };
65308 
65309 
65310 class ProducerPortProxy : public ::perfetto::ipc::ServiceProxy {
65311  public:
65312    explicit ProducerPortProxy(::perfetto::ipc::ServiceProxy::EventListener*);
65313    ~ProducerPortProxy() override;
65314 
65315   // ServiceProxy implementation.
65316   const ::perfetto::ipc::ServiceDescriptor& GetDescriptor() override;
65317 
65318   // Methods from the .proto file
65319   using DeferredInitializeConnectionResponse = ::perfetto::ipc::Deferred<InitializeConnectionResponse>;
65320   void InitializeConnection(const InitializeConnectionRequest&, DeferredInitializeConnectionResponse, int fd = -1);
65321 
65322   using DeferredRegisterDataSourceResponse = ::perfetto::ipc::Deferred<RegisterDataSourceResponse>;
65323   void RegisterDataSource(const RegisterDataSourceRequest&, DeferredRegisterDataSourceResponse, int fd = -1);
65324 
65325   using DeferredUnregisterDataSourceResponse = ::perfetto::ipc::Deferred<UnregisterDataSourceResponse>;
65326   void UnregisterDataSource(const UnregisterDataSourceRequest&, DeferredUnregisterDataSourceResponse, int fd = -1);
65327 
65328   using DeferredCommitDataResponse = ::perfetto::ipc::Deferred<CommitDataResponse>;
65329   void CommitData(const CommitDataRequest&, DeferredCommitDataResponse, int fd = -1);
65330 
65331   using DeferredGetAsyncCommandResponse = ::perfetto::ipc::Deferred<GetAsyncCommandResponse>;
65332   void GetAsyncCommand(const GetAsyncCommandRequest&, DeferredGetAsyncCommandResponse, int fd = -1);
65333 
65334   using DeferredRegisterTraceWriterResponse = ::perfetto::ipc::Deferred<RegisterTraceWriterResponse>;
65335   void RegisterTraceWriter(const RegisterTraceWriterRequest&, DeferredRegisterTraceWriterResponse, int fd = -1);
65336 
65337   using DeferredUnregisterTraceWriterResponse = ::perfetto::ipc::Deferred<UnregisterTraceWriterResponse>;
65338   void UnregisterTraceWriter(const UnregisterTraceWriterRequest&, DeferredUnregisterTraceWriterResponse, int fd = -1);
65339 
65340   using DeferredNotifyDataSourceStartedResponse = ::perfetto::ipc::Deferred<NotifyDataSourceStartedResponse>;
65341   void NotifyDataSourceStarted(const NotifyDataSourceStartedRequest&, DeferredNotifyDataSourceStartedResponse, int fd = -1);
65342 
65343   using DeferredNotifyDataSourceStoppedResponse = ::perfetto::ipc::Deferred<NotifyDataSourceStoppedResponse>;
65344   void NotifyDataSourceStopped(const NotifyDataSourceStoppedRequest&, DeferredNotifyDataSourceStoppedResponse, int fd = -1);
65345 
65346   using DeferredActivateTriggersResponse = ::perfetto::ipc::Deferred<ActivateTriggersResponse>;
65347   void ActivateTriggers(const ActivateTriggersRequest&, DeferredActivateTriggersResponse, int fd = -1);
65348 
65349   using DeferredSyncResponse = ::perfetto::ipc::Deferred<SyncResponse>;
65350   void Sync(const SyncRequest&, DeferredSyncResponse, int fd = -1);
65351 
65352 };
65353 
65354 }  // namespace perfetto
65355 }  // namespace protos
65356 }  // namespace gen
65357 
65358 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_PRODUCER_PORT_PROTO_H_
65359 // DO NOT EDIT. Autogenerated by Perfetto IPC
65360 // gen_amalgamated expanded: #include "protos/perfetto/ipc/producer_port.ipc.h"
65361 // gen_amalgamated expanded: #include "perfetto/ext/ipc/codegen_helpers.h"
65362 
65363 #include <memory>
65364 
65365 namespace perfetto {
65366 namespace protos {
65367 namespace gen {
NewDescriptor()65368 ::perfetto::ipc::ServiceDescriptor* ProducerPort::NewDescriptor() {
65369   auto* desc = new ::perfetto::ipc::ServiceDescriptor();
65370   desc->service_name = "ProducerPort";
65371 
65372   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
65373      "InitializeConnection",
65374      &_IPC_Decoder<InitializeConnectionRequest>,
65375      &_IPC_Decoder<InitializeConnectionResponse>,
65376      &_IPC_Invoker<ProducerPort, InitializeConnectionRequest, InitializeConnectionResponse, &ProducerPort::InitializeConnection>});
65377 
65378   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
65379      "RegisterDataSource",
65380      &_IPC_Decoder<RegisterDataSourceRequest>,
65381      &_IPC_Decoder<RegisterDataSourceResponse>,
65382      &_IPC_Invoker<ProducerPort, RegisterDataSourceRequest, RegisterDataSourceResponse, &ProducerPort::RegisterDataSource>});
65383 
65384   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
65385      "UnregisterDataSource",
65386      &_IPC_Decoder<UnregisterDataSourceRequest>,
65387      &_IPC_Decoder<UnregisterDataSourceResponse>,
65388      &_IPC_Invoker<ProducerPort, UnregisterDataSourceRequest, UnregisterDataSourceResponse, &ProducerPort::UnregisterDataSource>});
65389 
65390   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
65391      "CommitData",
65392      &_IPC_Decoder<CommitDataRequest>,
65393      &_IPC_Decoder<CommitDataResponse>,
65394      &_IPC_Invoker<ProducerPort, CommitDataRequest, CommitDataResponse, &ProducerPort::CommitData>});
65395 
65396   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
65397      "GetAsyncCommand",
65398      &_IPC_Decoder<GetAsyncCommandRequest>,
65399      &_IPC_Decoder<GetAsyncCommandResponse>,
65400      &_IPC_Invoker<ProducerPort, GetAsyncCommandRequest, GetAsyncCommandResponse, &ProducerPort::GetAsyncCommand>});
65401 
65402   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
65403      "RegisterTraceWriter",
65404      &_IPC_Decoder<RegisterTraceWriterRequest>,
65405      &_IPC_Decoder<RegisterTraceWriterResponse>,
65406      &_IPC_Invoker<ProducerPort, RegisterTraceWriterRequest, RegisterTraceWriterResponse, &ProducerPort::RegisterTraceWriter>});
65407 
65408   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
65409      "UnregisterTraceWriter",
65410      &_IPC_Decoder<UnregisterTraceWriterRequest>,
65411      &_IPC_Decoder<UnregisterTraceWriterResponse>,
65412      &_IPC_Invoker<ProducerPort, UnregisterTraceWriterRequest, UnregisterTraceWriterResponse, &ProducerPort::UnregisterTraceWriter>});
65413 
65414   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
65415      "NotifyDataSourceStarted",
65416      &_IPC_Decoder<NotifyDataSourceStartedRequest>,
65417      &_IPC_Decoder<NotifyDataSourceStartedResponse>,
65418      &_IPC_Invoker<ProducerPort, NotifyDataSourceStartedRequest, NotifyDataSourceStartedResponse, &ProducerPort::NotifyDataSourceStarted>});
65419 
65420   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
65421      "NotifyDataSourceStopped",
65422      &_IPC_Decoder<NotifyDataSourceStoppedRequest>,
65423      &_IPC_Decoder<NotifyDataSourceStoppedResponse>,
65424      &_IPC_Invoker<ProducerPort, NotifyDataSourceStoppedRequest, NotifyDataSourceStoppedResponse, &ProducerPort::NotifyDataSourceStopped>});
65425 
65426   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
65427      "ActivateTriggers",
65428      &_IPC_Decoder<ActivateTriggersRequest>,
65429      &_IPC_Decoder<ActivateTriggersResponse>,
65430      &_IPC_Invoker<ProducerPort, ActivateTriggersRequest, ActivateTriggersResponse, &ProducerPort::ActivateTriggers>});
65431 
65432   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
65433      "Sync",
65434      &_IPC_Decoder<SyncRequest>,
65435      &_IPC_Decoder<SyncResponse>,
65436      &_IPC_Invoker<ProducerPort, SyncRequest, SyncResponse, &ProducerPort::Sync>});
65437   desc->methods.shrink_to_fit();
65438   return desc;
65439 }
65440 
65441 
GetDescriptorStatic()65442 const ::perfetto::ipc::ServiceDescriptor& ProducerPort::GetDescriptorStatic() {
65443   static auto* instance = NewDescriptor();
65444   return *instance;
65445 }
65446 
65447 // Host-side definitions.
65448 ProducerPort::~ProducerPort() = default;
65449 
GetDescriptor()65450 const ::perfetto::ipc::ServiceDescriptor& ProducerPort::GetDescriptor() {
65451   return GetDescriptorStatic();
65452 }
65453 
65454 // Client-side definitions.
ProducerPortProxy(::perfetto::ipc::ServiceProxy::EventListener * event_listener)65455 ProducerPortProxy::ProducerPortProxy(::perfetto::ipc::ServiceProxy::EventListener* event_listener)
65456     : ::perfetto::ipc::ServiceProxy(event_listener) {}
65457 
65458 ProducerPortProxy::~ProducerPortProxy() = default;
65459 
GetDescriptor()65460 const ::perfetto::ipc::ServiceDescriptor& ProducerPortProxy::GetDescriptor() {
65461   return ProducerPort::GetDescriptorStatic();
65462 }
65463 
InitializeConnection(const InitializeConnectionRequest & request,DeferredInitializeConnectionResponse reply,int fd)65464 void ProducerPortProxy::InitializeConnection(const InitializeConnectionRequest& request, DeferredInitializeConnectionResponse reply, int fd) {
65465   BeginInvoke("InitializeConnection", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
65466               fd);
65467 }
65468 
RegisterDataSource(const RegisterDataSourceRequest & request,DeferredRegisterDataSourceResponse reply,int fd)65469 void ProducerPortProxy::RegisterDataSource(const RegisterDataSourceRequest& request, DeferredRegisterDataSourceResponse reply, int fd) {
65470   BeginInvoke("RegisterDataSource", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
65471               fd);
65472 }
65473 
UnregisterDataSource(const UnregisterDataSourceRequest & request,DeferredUnregisterDataSourceResponse reply,int fd)65474 void ProducerPortProxy::UnregisterDataSource(const UnregisterDataSourceRequest& request, DeferredUnregisterDataSourceResponse reply, int fd) {
65475   BeginInvoke("UnregisterDataSource", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
65476               fd);
65477 }
65478 
CommitData(const CommitDataRequest & request,DeferredCommitDataResponse reply,int fd)65479 void ProducerPortProxy::CommitData(const CommitDataRequest& request, DeferredCommitDataResponse reply, int fd) {
65480   BeginInvoke("CommitData", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
65481               fd);
65482 }
65483 
GetAsyncCommand(const GetAsyncCommandRequest & request,DeferredGetAsyncCommandResponse reply,int fd)65484 void ProducerPortProxy::GetAsyncCommand(const GetAsyncCommandRequest& request, DeferredGetAsyncCommandResponse reply, int fd) {
65485   BeginInvoke("GetAsyncCommand", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
65486               fd);
65487 }
65488 
RegisterTraceWriter(const RegisterTraceWriterRequest & request,DeferredRegisterTraceWriterResponse reply,int fd)65489 void ProducerPortProxy::RegisterTraceWriter(const RegisterTraceWriterRequest& request, DeferredRegisterTraceWriterResponse reply, int fd) {
65490   BeginInvoke("RegisterTraceWriter", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
65491               fd);
65492 }
65493 
UnregisterTraceWriter(const UnregisterTraceWriterRequest & request,DeferredUnregisterTraceWriterResponse reply,int fd)65494 void ProducerPortProxy::UnregisterTraceWriter(const UnregisterTraceWriterRequest& request, DeferredUnregisterTraceWriterResponse reply, int fd) {
65495   BeginInvoke("UnregisterTraceWriter", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
65496               fd);
65497 }
65498 
NotifyDataSourceStarted(const NotifyDataSourceStartedRequest & request,DeferredNotifyDataSourceStartedResponse reply,int fd)65499 void ProducerPortProxy::NotifyDataSourceStarted(const NotifyDataSourceStartedRequest& request, DeferredNotifyDataSourceStartedResponse reply, int fd) {
65500   BeginInvoke("NotifyDataSourceStarted", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
65501               fd);
65502 }
65503 
NotifyDataSourceStopped(const NotifyDataSourceStoppedRequest & request,DeferredNotifyDataSourceStoppedResponse reply,int fd)65504 void ProducerPortProxy::NotifyDataSourceStopped(const NotifyDataSourceStoppedRequest& request, DeferredNotifyDataSourceStoppedResponse reply, int fd) {
65505   BeginInvoke("NotifyDataSourceStopped", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
65506               fd);
65507 }
65508 
ActivateTriggers(const ActivateTriggersRequest & request,DeferredActivateTriggersResponse reply,int fd)65509 void ProducerPortProxy::ActivateTriggers(const ActivateTriggersRequest& request, DeferredActivateTriggersResponse reply, int fd) {
65510   BeginInvoke("ActivateTriggers", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
65511               fd);
65512 }
65513 
Sync(const SyncRequest & request,DeferredSyncResponse reply,int fd)65514 void ProducerPortProxy::Sync(const SyncRequest& request, DeferredSyncResponse reply, int fd) {
65515   BeginInvoke("Sync", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
65516               fd);
65517 }
65518 }  // namespace perfetto
65519 }  // namespace protos
65520 }  // namespace gen
65521 // gen_amalgamated begin source: src/tracing/ipc/default_socket.cc
65522 // gen_amalgamated begin header: include/perfetto/ext/tracing/ipc/default_socket.h
65523 /*
65524  * Copyright (C) 2018 The Android Open Source Project
65525  *
65526  * Licensed under the Apache License, Version 2.0 (the "License");
65527  * you may not use this file except in compliance with the License.
65528  * You may obtain a copy of the License at
65529  *
65530  *      http://www.apache.org/licenses/LICENSE-2.0
65531  *
65532  * Unless required by applicable law or agreed to in writing, software
65533  * distributed under the License is distributed on an "AS IS" BASIS,
65534  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65535  * See the License for the specific language governing permissions and
65536  * limitations under the License.
65537  */
65538 
65539 #ifndef INCLUDE_PERFETTO_EXT_TRACING_IPC_DEFAULT_SOCKET_H_
65540 #define INCLUDE_PERFETTO_EXT_TRACING_IPC_DEFAULT_SOCKET_H_
65541 
65542 // gen_amalgamated expanded: #include "perfetto/base/export.h"
65543 
65544 namespace perfetto {
65545 
65546 PERFETTO_EXPORT const char* GetConsumerSocket();
65547 PERFETTO_EXPORT const char* GetProducerSocket();
65548 
65549 }  // namespace perfetto
65550 
65551 #endif  // INCLUDE_PERFETTO_EXT_TRACING_IPC_DEFAULT_SOCKET_H_
65552 /*
65553  * Copyright (C) 2018 The Android Open Source Project
65554  *
65555  * Licensed under the Apache License, Version 2.0 (the "License");
65556  * you may not use this file except in compliance with the License.
65557  * You may obtain a copy of the License at
65558  *
65559  *      http://www.apache.org/licenses/LICENSE-2.0
65560  *
65561  * Unless required by applicable law or agreed to in writing, software
65562  * distributed under the License is distributed on an "AS IS" BASIS,
65563  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65564  * See the License for the specific language governing permissions and
65565  * limitations under the License.
65566  */
65567 
65568 // gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/default_socket.h"
65569 
65570 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
65571 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
65572 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
65573 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
65574 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
65575 
65576 #include <stdlib.h>
65577 #include <unistd.h>
65578 
65579 namespace perfetto {
65580 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
65581 // On non-Android platforms, check /run/perfetto/ before using /tmp/ as the
65582 // socket base directory.
65583 namespace {
65584 const char* kRunPerfettoBaseDir = "/run/perfetto/";
65585 
UseRunPerfettoBaseDir()65586 bool UseRunPerfettoBaseDir() {
65587 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
65588     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
65589     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
65590   // Note that the trailing / in |kRunPerfettoBaseDir| ensures we are checking
65591   // against a directory, not a file.
65592   int res = PERFETTO_EINTR(access(kRunPerfettoBaseDir, X_OK));
65593   if (!res)
65594     return true;
65595 
65596   // If the path doesn't exist (ENOENT), fail silently to the caller. Otherwise,
65597   // fail with an explicit error message.
65598   if (errno != ENOENT) {
65599     PERFETTO_PLOG("%s exists but cannot be accessed. Falling back on /tmp/ ",
65600                   kRunPerfettoBaseDir);
65601   }
65602   return false;
65603 #else
65604   return false;
65605 #endif
65606 }
65607 
65608 }  // anonymous namespace
65609 #endif  // !PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
65610 
65611 static_assert(kInvalidUid == ipc::kInvalidUid, "kInvalidUid mismatching");
65612 
GetProducerSocket()65613 const char* GetProducerSocket() {
65614   const char* name = getenv("PERFETTO_PRODUCER_SOCK_NAME");
65615   if (name == nullptr) {
65616 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
65617     name = "127.0.0.1:32278";
65618 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
65619     name = "/dev/socket/traced_producer";
65620 #else
65621     // Use /run/perfetto if it exists. Then fallback to /tmp.
65622     static const char* producer_socket =
65623         UseRunPerfettoBaseDir() ? "/run/perfetto/traced-producer.sock"
65624                                 : "/tmp/perfetto-producer";
65625     name = producer_socket;
65626 #endif
65627   }
65628   return name;
65629 }
65630 
GetConsumerSocket()65631 const char* GetConsumerSocket() {
65632   const char* name = getenv("PERFETTO_CONSUMER_SOCK_NAME");
65633   if (name == nullptr) {
65634 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
65635     name = "127.0.0.1:32279";
65636 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
65637     name = "/dev/socket/traced_consumer";
65638 #else
65639     // Use /run/perfetto if it exists. Then fallback to /tmp.
65640     static const char* consumer_socket =
65641         UseRunPerfettoBaseDir() ? "/run/perfetto/traced-consumer.sock"
65642                                 : "/tmp/perfetto-consumer";
65643     name = consumer_socket;
65644 #endif
65645   }
65646   return name;
65647 }
65648 
65649 }  // namespace perfetto
65650 // gen_amalgamated begin source: src/tracing/ipc/memfd.cc
65651 // gen_amalgamated begin header: src/tracing/ipc/memfd.h
65652 /*
65653  * Copyright (C) 2020 The Android Open Source Project
65654  *
65655  * Licensed under the Apache License, Version 2.0 (the "License");
65656  * you may not use this file except in compliance with the License.
65657  * You may obtain a copy of the License at
65658  *
65659  *      http://www.apache.org/licenses/LICENSE-2.0
65660  *
65661  * Unless required by applicable law or agreed to in writing, software
65662  * distributed under the License is distributed on an "AS IS" BASIS,
65663  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65664  * See the License for the specific language governing permissions and
65665  * limitations under the License.
65666  */
65667 
65668 #ifndef SRC_TRACING_IPC_MEMFD_H_
65669 #define SRC_TRACING_IPC_MEMFD_H_
65670 
65671 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
65672 
65673 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
65674 
65675 // Some android build bots use a sysroot that doesn't support memfd when
65676 // compiling for the host, so we define the flags we need ourselves.
65677 
65678 // from memfd.h
65679 #ifndef MFD_CLOEXEC
65680 #define MFD_CLOEXEC 0x0001U
65681 #define MFD_ALLOW_SEALING 0x0002U
65682 #endif
65683 
65684 // from fcntl.h
65685 #ifndef F_ADD_SEALS
65686 #define F_ADD_SEALS 1033
65687 #define F_GET_SEALS 1034
65688 #define F_SEAL_SEAL 0x0001
65689 #define F_SEAL_SHRINK 0x0002
65690 #define F_SEAL_GROW 0x0004
65691 #define F_SEAL_WRITE 0x0008
65692 #endif
65693 
65694 namespace perfetto {
65695 
65696 // Whether the operating system supports memfd.
65697 bool HasMemfdSupport();
65698 
65699 // Call memfd(2) if available on platform and return the fd as result. This call
65700 // also makes a kernel version check for safety on older kernels (b/116769556).
65701 // Returns an invalid ScopedFile on failure.
65702 base::ScopedFile CreateMemfd(const char* name, unsigned int flags);
65703 
65704 }  // namespace perfetto
65705 
65706 #endif  // SRC_TRACING_IPC_MEMFD_H_
65707 /*
65708  * Copyright (C) 2020 The Android Open Source Project
65709  *
65710  * Licensed under the Apache License, Version 2.0 (the "License");
65711  * you may not use this file except in compliance with the License.
65712  * You may obtain a copy of the License at
65713  *
65714  *      http://www.apache.org/licenses/LICENSE-2.0
65715  *
65716  * Unless required by applicable law or agreed to in writing, software
65717  * distributed under the License is distributed on an "AS IS" BASIS,
65718  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65719  * See the License for the specific language governing permissions and
65720  * limitations under the License.
65721  */
65722 
65723 // gen_amalgamated expanded: #include "src/tracing/ipc/memfd.h"
65724 
65725 #include <errno.h>
65726 
65727 #define PERFETTO_MEMFD_ENABLED()             \
65728   PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
65729       PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX)
65730 
65731 #if PERFETTO_MEMFD_ENABLED()
65732 
65733 #include <stdio.h>
65734 #include <string.h>
65735 #include <sys/syscall.h>
65736 #include <sys/utsname.h>
65737 #include <unistd.h>
65738 
65739 // Some android build bots use a sysroot that doesn't support memfd when
65740 // compiling for the host, so we redefine it if necessary.
65741 #if !defined(__NR_memfd_create)
65742 #if defined(__x86_64__)
65743 #define __NR_memfd_create 319
65744 #elif defined(__i386__)
65745 #define __NR_memfd_create 356
65746 #elif defined(__aarch64__)
65747 #define __NR_memfd_create 279
65748 #elif defined(__arm__)
65749 #define __NR_memfd_create 385
65750 #else
65751 #error "unsupported sysroot without memfd support"
65752 #endif
65753 #endif  // !defined(__NR_memfd_create)
65754 
65755 namespace perfetto {
HasMemfdSupport()65756 bool HasMemfdSupport() {
65757   static bool kSupportsMemfd = [] {
65758     // Check kernel version supports memfd_create(). Some older kernels segfault
65759     // executing memfd_create() rather than returning ENOSYS (b/116769556).
65760     static constexpr int kRequiredMajor = 3;
65761     static constexpr int kRequiredMinor = 17;
65762     struct utsname uts;
65763     int major, minor;
65764     if (uname(&uts) == 0 && strcmp(uts.sysname, "Linux") == 0 &&
65765         sscanf(uts.release, "%d.%d", &major, &minor) == 2 &&
65766         ((major < kRequiredMajor ||
65767           (major == kRequiredMajor && minor < kRequiredMinor)))) {
65768       return false;
65769     }
65770 
65771     base::ScopedFile fd;
65772     fd.reset(static_cast<int>(syscall(__NR_memfd_create, "perfetto_shmem",
65773                                       MFD_CLOEXEC | MFD_ALLOW_SEALING)));
65774     return !!fd;
65775   }();
65776   return kSupportsMemfd;
65777 }
65778 
CreateMemfd(const char * name,unsigned int flags)65779 base::ScopedFile CreateMemfd(const char* name, unsigned int flags) {
65780   if (!HasMemfdSupport()) {
65781     errno = ENOSYS;
65782     return base::ScopedFile();
65783   }
65784   return base::ScopedFile(
65785       static_cast<int>(syscall(__NR_memfd_create, name, flags)));
65786 }
65787 }  // namespace perfetto
65788 
65789 #else  // PERFETTO_MEMFD_ENABLED()
65790 
65791 namespace perfetto {
HasMemfdSupport()65792 bool HasMemfdSupport() {
65793   return false;
65794 }
CreateMemfd(const char *,unsigned int)65795 base::ScopedFile CreateMemfd(const char*, unsigned int) {
65796   errno = ENOSYS;
65797   return base::ScopedFile();
65798 }
65799 }  // namespace perfetto
65800 
65801 #endif  // PERFETTO_MEMFD_ENABLED()
65802 // gen_amalgamated begin source: src/tracing/ipc/posix_shared_memory.cc
65803 // gen_amalgamated begin header: src/tracing/ipc/posix_shared_memory.h
65804 /*
65805  * Copyright (C) 2017 The Android Open Source Project
65806  *
65807  * Licensed under the Apache License, Version 2.0 (the "License");
65808  * you may not use this file except in compliance with the License.
65809  * You may obtain a copy of the License at
65810  *
65811  *      http://www.apache.org/licenses/LICENSE-2.0
65812  *
65813  * Unless required by applicable law or agreed to in writing, software
65814  * distributed under the License is distributed on an "AS IS" BASIS,
65815  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65816  * See the License for the specific language governing permissions and
65817  * limitations under the License.
65818  */
65819 
65820 #ifndef SRC_TRACING_IPC_POSIX_SHARED_MEMORY_H_
65821 #define SRC_TRACING_IPC_POSIX_SHARED_MEMORY_H_
65822 
65823 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
65824 
65825 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
65826     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
65827     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
65828 
65829 #include <stddef.h>
65830 
65831 #include <memory>
65832 
65833 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
65834 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
65835 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
65836 
65837 namespace perfetto {
65838 
65839 // Implements the SharedMemory and its factory for the posix-based transport.
65840 class PosixSharedMemory : public SharedMemory {
65841  public:
65842   class Factory : public SharedMemory::Factory {
65843    public:
65844     ~Factory() override;
65845     std::unique_ptr<SharedMemory> CreateSharedMemory(size_t) override;
65846   };
65847 
65848   // Create a brand new SHM region.
65849   static std::unique_ptr<PosixSharedMemory> Create(size_t size);
65850 
65851   // Mmaps a file descriptor to an existing SHM region. If
65852   // |require_seals_if_supported| is true and the system supports
65853   // memfd_create(), the FD is required to be a sealed memfd with F_SEAL_SEAL,
65854   // F_SEAL_GROW, and F_SEAL_SHRINK seals set (otherwise, nullptr is returned).
65855   // May also return nullptr if mapping fails for another reason (e.g. OOM).
65856   static std::unique_ptr<PosixSharedMemory> AttachToFd(
65857       base::ScopedFile,
65858       bool require_seals_if_supported = true);
65859 
65860   ~PosixSharedMemory() override;
65861 
fd() const65862   int fd() const { return fd_.get(); }
65863 
65864   // SharedMemory implementation.
start() const65865   void* start() const override { return start_; }
size() const65866   size_t size() const override { return size_; }
65867 
65868  private:
65869   static std::unique_ptr<PosixSharedMemory> MapFD(base::ScopedFile, size_t);
65870 
65871   PosixSharedMemory(void* start, size_t size, base::ScopedFile);
65872   PosixSharedMemory(const PosixSharedMemory&) = delete;
65873   PosixSharedMemory& operator=(const PosixSharedMemory&) = delete;
65874 
65875   void* const start_;
65876   const size_t size_;
65877   base::ScopedFile fd_;
65878 };
65879 
65880 }  // namespace perfetto
65881 
65882 #endif  // OS_LINUX || OS_ANDROID || OS_APPLE
65883 #endif  // SRC_TRACING_IPC_POSIX_SHARED_MEMORY_H_
65884 /*
65885  * Copyright (C) 2017 The Android Open Source Project
65886  *
65887  * Licensed under the Apache License, Version 2.0 (the "License");
65888  * you may not use this file except in compliance with the License.
65889  * You may obtain a copy of the License at
65890  *
65891  *      http://www.apache.org/licenses/LICENSE-2.0
65892  *
65893  * Unless required by applicable law or agreed to in writing, software
65894  * distributed under the License is distributed on an "AS IS" BASIS,
65895  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65896  * See the License for the specific language governing permissions and
65897  * limitations under the License.
65898  */
65899 
65900 // gen_amalgamated expanded: #include "src/tracing/ipc/posix_shared_memory.h"
65901 
65902 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
65903     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
65904     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
65905 
65906 #include <fcntl.h>
65907 #include <stdint.h>
65908 #include <stdio.h>
65909 #include <stdlib.h>
65910 #include <sys/mman.h>
65911 #include <sys/stat.h>
65912 #include <unistd.h>
65913 
65914 #include <memory>
65915 #include <utility>
65916 
65917 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
65918 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
65919 // gen_amalgamated expanded: #include "perfetto/ext/base/temp_file.h"
65920 // gen_amalgamated expanded: #include "src/tracing/ipc/memfd.h"
65921 
65922 namespace perfetto {
65923 
65924 namespace {
65925 int kFileSeals = F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_SEAL;
65926 }  // namespace
65927 
65928 // static
Create(size_t size)65929 std::unique_ptr<PosixSharedMemory> PosixSharedMemory::Create(size_t size) {
65930   base::ScopedFile fd =
65931       CreateMemfd("perfetto_shmem", MFD_CLOEXEC | MFD_ALLOW_SEALING);
65932   bool is_memfd = !!fd;
65933 
65934   // In-tree builds only allow mem_fd, so we can inspect the seals to verify the
65935   // fd is appropriately sealed. We'll crash in the PERFETTO_CHECK(fd) below if
65936   // memfd_create failed.
65937 #if !PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
65938   if (!fd) {
65939     // TODO: if this fails on Android we should fall back on ashmem.
65940     PERFETTO_DPLOG("memfd_create() failed");
65941     fd = base::TempFile::CreateUnlinked().ReleaseFD();
65942   }
65943 #endif
65944 
65945   PERFETTO_CHECK(fd);
65946   int res = ftruncate(fd.get(), static_cast<off_t>(size));
65947   PERFETTO_CHECK(res == 0);
65948 
65949   if (is_memfd) {
65950     // When memfd is supported, file seals should be, too.
65951     res = fcntl(*fd, F_ADD_SEALS, kFileSeals);
65952     PERFETTO_DCHECK(res == 0);
65953   }
65954 
65955   return MapFD(std::move(fd), size);
65956 }
65957 
65958 // static
AttachToFd(base::ScopedFile fd,bool require_seals_if_supported)65959 std::unique_ptr<PosixSharedMemory> PosixSharedMemory::AttachToFd(
65960     base::ScopedFile fd,
65961     bool require_seals_if_supported) {
65962   bool requires_seals = require_seals_if_supported;
65963 
65964 #if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
65965   // In-tree kernels all support memfd.
65966   PERFETTO_CHECK(HasMemfdSupport());
65967 #else
65968   // In out-of-tree builds, we only require seals if the kernel supports memfd.
65969   if (requires_seals)
65970     requires_seals = HasMemfdSupport();
65971 #endif
65972 
65973   if (requires_seals) {
65974     // If the system supports memfd, we require a sealed memfd.
65975     int res = fcntl(*fd, F_GET_SEALS);
65976     if (res == -1 || (res & kFileSeals) != kFileSeals) {
65977       PERFETTO_PLOG("Couldn't verify file seals on shmem FD");
65978       return nullptr;
65979     }
65980   }
65981 
65982   struct stat stat_buf = {};
65983   int res = fstat(fd.get(), &stat_buf);
65984   PERFETTO_CHECK(res == 0 && stat_buf.st_size > 0);
65985   return MapFD(std::move(fd), static_cast<size_t>(stat_buf.st_size));
65986 }
65987 
65988 // static
MapFD(base::ScopedFile fd,size_t size)65989 std::unique_ptr<PosixSharedMemory> PosixSharedMemory::MapFD(base::ScopedFile fd,
65990                                                             size_t size) {
65991   PERFETTO_DCHECK(fd);
65992   PERFETTO_DCHECK(size > 0);
65993   void* start =
65994       mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd.get(), 0);
65995   PERFETTO_CHECK(start != MAP_FAILED);
65996   return std::unique_ptr<PosixSharedMemory>(
65997       new PosixSharedMemory(start, size, std::move(fd)));
65998 }
65999 
PosixSharedMemory(void * start,size_t size,base::ScopedFile fd)66000 PosixSharedMemory::PosixSharedMemory(void* start,
66001                                      size_t size,
66002                                      base::ScopedFile fd)
66003     : start_(start), size_(size), fd_(std::move(fd)) {}
66004 
~PosixSharedMemory()66005 PosixSharedMemory::~PosixSharedMemory() {
66006   munmap(start(), size());
66007 }
66008 
~Factory()66009 PosixSharedMemory::Factory::~Factory() {}
66010 
CreateSharedMemory(size_t size)66011 std::unique_ptr<SharedMemory> PosixSharedMemory::Factory::CreateSharedMemory(
66012     size_t size) {
66013   return PosixSharedMemory::Create(size);
66014 }
66015 
66016 }  // namespace perfetto
66017 
66018 #endif  // OS_LINUX || OS_ANDROID || OS_APPLE
66019 // gen_amalgamated begin source: src/tracing/ipc/consumer/consumer_ipc_client_impl.cc
66020 // gen_amalgamated begin header: src/tracing/ipc/consumer/consumer_ipc_client_impl.h
66021 // gen_amalgamated begin header: include/perfetto/ext/tracing/ipc/consumer_ipc_client.h
66022 /*
66023  * Copyright (C) 2017 The Android Open Source Project
66024  *
66025  * Licensed under the Apache License, Version 2.0 (the "License");
66026  * you may not use this file except in compliance with the License.
66027  * You may obtain a copy of the License at
66028  *
66029  *      http://www.apache.org/licenses/LICENSE-2.0
66030  *
66031  * Unless required by applicable law or agreed to in writing, software
66032  * distributed under the License is distributed on an "AS IS" BASIS,
66033  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66034  * See the License for the specific language governing permissions and
66035  * limitations under the License.
66036  */
66037 
66038 #ifndef INCLUDE_PERFETTO_EXT_TRACING_IPC_CONSUMER_IPC_CLIENT_H_
66039 #define INCLUDE_PERFETTO_EXT_TRACING_IPC_CONSUMER_IPC_CLIENT_H_
66040 
66041 #include <memory>
66042 #include <string>
66043 
66044 // gen_amalgamated expanded: #include "perfetto/base/export.h"
66045 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
66046 
66047 namespace perfetto {
66048 
66049 class Consumer;
66050 
66051 // Allows to connect to a remote Service through a UNIX domain socket.
66052 // Exposed to:
66053 //   Consumer(s) of the tracing library.
66054 // Implemented in:
66055 //   src/tracing/ipc/consumer/consumer_ipc_client_impl.cc
66056 class PERFETTO_EXPORT ConsumerIPCClient {
66057  public:
66058   // Connects to the producer port of the Service listening on the given
66059   // |service_sock_name|. If the connection is successful, the OnConnect()
66060   // method will be invoked asynchronously on the passed Consumer interface.
66061   // If the connection fails, OnDisconnect() will be invoked instead.
66062   // The returned ConsumerEndpoint serves also to delimit the scope of the
66063   // callbacks invoked on the Consumer interface: no more Consumer callbacks are
66064   // invoked immediately after its destruction and any pending callback will be
66065   // dropped.
66066   static std::unique_ptr<TracingService::ConsumerEndpoint>
66067   Connect(const char* service_sock_name, Consumer*, base::TaskRunner*);
66068 
66069  protected:
66070   ConsumerIPCClient() = delete;
66071 };
66072 
66073 }  // namespace perfetto
66074 
66075 #endif  // INCLUDE_PERFETTO_EXT_TRACING_IPC_CONSUMER_IPC_CLIENT_H_
66076 /*
66077  * Copyright (C) 2017 The Android Open Source Project
66078  *
66079  * Licensed under the Apache License, Version 2.0 (the "License");
66080  * you may not use this file except in compliance with the License.
66081  * You may obtain a copy of the License at
66082  *
66083  *      http://www.apache.org/licenses/LICENSE-2.0
66084  *
66085  * Unless required by applicable law or agreed to in writing, software
66086  * distributed under the License is distributed on an "AS IS" BASIS,
66087  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66088  * See the License for the specific language governing permissions and
66089  * limitations under the License.
66090  */
66091 
66092 #ifndef SRC_TRACING_IPC_CONSUMER_CONSUMER_IPC_CLIENT_IMPL_H_
66093 #define SRC_TRACING_IPC_CONSUMER_CONSUMER_IPC_CLIENT_IMPL_H_
66094 
66095 #include <stdint.h>
66096 
66097 #include <list>
66098 #include <vector>
66099 
66100 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
66101 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
66102 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
66103 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
66104 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
66105 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
66106 // gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/consumer_ipc_client.h"
66107 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
66108 
66109 // gen_amalgamated expanded: #include "protos/perfetto/ipc/consumer_port.ipc.h"
66110 
66111 namespace perfetto {
66112 
66113 namespace base {
66114 class TaskRunner;
66115 }  // namespace base
66116 
66117 namespace ipc {
66118 class Client;
66119 }  // namespace ipc
66120 
66121 class Consumer;
66122 
66123 // Exposes a Service endpoint to Consumer(s), proxying all requests through a
66124 // IPC channel to the remote Service. This class is the glue layer between the
66125 // generic Service interface exposed to the clients of the library and the
66126 // actual IPC transport.
66127 class ConsumerIPCClientImpl : public TracingService::ConsumerEndpoint,
66128                               public ipc::ServiceProxy::EventListener {
66129  public:
66130   ConsumerIPCClientImpl(const char* service_sock_name,
66131                         Consumer*,
66132                         base::TaskRunner*);
66133   ~ConsumerIPCClientImpl() override;
66134 
66135   // TracingService::ConsumerEndpoint implementation.
66136   // These methods are invoked by the actual Consumer(s) code by clients of the
66137   // tracing library, which know nothing about the IPC transport.
66138   void EnableTracing(const TraceConfig&, base::ScopedFile) override;
66139   void StartTracing() override;
66140   void ChangeTraceConfig(const TraceConfig&) override;
66141   void DisableTracing() override;
66142   void ReadBuffers() override;
66143   void FreeBuffers() override;
66144   void Flush(uint32_t timeout_ms, FlushCallback) override;
66145   void Detach(const std::string& key) override;
66146   void Attach(const std::string& key) override;
66147   void GetTraceStats() override;
66148   void ObserveEvents(uint32_t enabled_event_types) override;
66149   void QueryServiceState(QueryServiceStateCallback) override;
66150   void QueryCapabilities(QueryCapabilitiesCallback) override;
66151   void SaveTraceForBugreport(SaveTraceForBugreportCallback) override;
66152 
66153   // ipc::ServiceProxy::EventListener implementation.
66154   // These methods are invoked by the IPC layer, which knows nothing about
66155   // tracing, consumers and consumers.
66156   void OnConnect() override;
66157   void OnDisconnect() override;
66158 
66159  private:
66160   struct PendingQueryServiceRequest {
66161     QueryServiceStateCallback callback;
66162 
66163     // All the replies will be appended here until |has_more| == false.
66164     std::vector<uint8_t> merged_resp;
66165   };
66166 
66167   // List because we need stable iterators.
66168   using PendingQueryServiceRequests = std::list<PendingQueryServiceRequest>;
66169 
66170   void OnReadBuffersResponse(
66171       ipc::AsyncResult<protos::gen::ReadBuffersResponse>);
66172   void OnEnableTracingResponse(
66173       ipc::AsyncResult<protos::gen::EnableTracingResponse>);
66174   void OnQueryServiceStateResponse(
66175       ipc::AsyncResult<protos::gen::QueryServiceStateResponse>,
66176       PendingQueryServiceRequests::iterator);
66177 
66178   // TODO(primiano): think to dtor order, do we rely on any specific sequence?
66179   Consumer* const consumer_;
66180 
66181   // The object that owns the client socket and takes care of IPC traffic.
66182   std::unique_ptr<ipc::Client> ipc_channel_;
66183 
66184   // The proxy interface for the consumer port of the service. It is bound
66185   // to |ipc_channel_| and (de)serializes method invocations over the wire.
66186   protos::gen::ConsumerPortProxy consumer_port_;
66187 
66188   bool connected_ = false;
66189 
66190   PendingQueryServiceRequests pending_query_svc_reqs_;
66191 
66192   // When a packet is too big to fit into a ReadBuffersResponse IPC, the service
66193   // will chunk it into several IPCs, each containing few slices of the packet
66194   // (a packet's slice is always guaranteed to be << kIPCBufferSize). When
66195   // chunking happens this field accumulates the slices received until the
66196   // one with |last_slice_for_packet| == true is received.
66197   TracePacket partial_packet_;
66198 
66199   // Keep last.
66200   base::WeakPtrFactory<ConsumerIPCClientImpl> weak_ptr_factory_;
66201 };
66202 
66203 }  // namespace perfetto
66204 
66205 #endif  // SRC_TRACING_IPC_CONSUMER_CONSUMER_IPC_CLIENT_IMPL_H_
66206 /*
66207  * Copyright (C) 2017 The Android Open Source Project
66208  *
66209  * Licensed under the Apache License, Version 2.0 (the "License");
66210  * you may not use this file except in compliance with the License.
66211  * You may obtain a copy of the License at
66212  *
66213  *      http://www.apache.org/licenses/LICENSE-2.0
66214  *
66215  * Unless required by applicable law or agreed to in writing, software
66216  * distributed under the License is distributed on an "AS IS" BASIS,
66217  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66218  * See the License for the specific language governing permissions and
66219  * limitations under the License.
66220  */
66221 
66222 // gen_amalgamated expanded: #include "src/tracing/ipc/consumer/consumer_ipc_client_impl.h"
66223 
66224 #include <inttypes.h>
66225 #include <string.h>
66226 
66227 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
66228 // gen_amalgamated expanded: #include "perfetto/ext/ipc/client.h"
66229 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
66230 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/observable_events.h"
66231 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_stats.h"
66232 // gen_amalgamated expanded: #include "perfetto/tracing/core/trace_config.h"
66233 // gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_state.h"
66234 
66235 // TODO(fmayer): Add a test to check to what happens when ConsumerIPCClientImpl
66236 // gets destroyed w.r.t. the Consumer pointer. Also think to lifetime of the
66237 // Consumer* during the callbacks.
66238 
66239 namespace perfetto {
66240 
66241 // static. (Declared in include/tracing/ipc/consumer_ipc_client.h).
Connect(const char * service_sock_name,Consumer * consumer,base::TaskRunner * task_runner)66242 std::unique_ptr<TracingService::ConsumerEndpoint> ConsumerIPCClient::Connect(
66243     const char* service_sock_name,
66244     Consumer* consumer,
66245     base::TaskRunner* task_runner) {
66246   return std::unique_ptr<TracingService::ConsumerEndpoint>(
66247       new ConsumerIPCClientImpl(service_sock_name, consumer, task_runner));
66248 }
66249 
ConsumerIPCClientImpl(const char * service_sock_name,Consumer * consumer,base::TaskRunner * task_runner)66250 ConsumerIPCClientImpl::ConsumerIPCClientImpl(const char* service_sock_name,
66251                                              Consumer* consumer,
66252                                              base::TaskRunner* task_runner)
66253     : consumer_(consumer),
66254       ipc_channel_(
66255           ipc::Client::CreateInstance({service_sock_name, /*sock_retry=*/false},
66256                                       task_runner)),
66257       consumer_port_(this /* event_listener */),
66258       weak_ptr_factory_(this) {
66259   ipc_channel_->BindService(consumer_port_.GetWeakPtr());
66260 }
66261 
66262 ConsumerIPCClientImpl::~ConsumerIPCClientImpl() = default;
66263 
66264 // Called by the IPC layer if the BindService() succeeds.
OnConnect()66265 void ConsumerIPCClientImpl::OnConnect() {
66266   connected_ = true;
66267   consumer_->OnConnect();
66268 }
66269 
OnDisconnect()66270 void ConsumerIPCClientImpl::OnDisconnect() {
66271   PERFETTO_DLOG("Tracing service connection failure");
66272   connected_ = false;
66273   consumer_->OnDisconnect();  // Note: may delete |this|.
66274 }
66275 
EnableTracing(const TraceConfig & trace_config,base::ScopedFile fd)66276 void ConsumerIPCClientImpl::EnableTracing(const TraceConfig& trace_config,
66277                                           base::ScopedFile fd) {
66278   if (!connected_) {
66279     PERFETTO_DLOG("Cannot EnableTracing(), not connected to tracing service");
66280     return;
66281   }
66282 
66283 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
66284   if (fd) {
66285     consumer_->OnTracingDisabled(
66286         "Passing FDs for write_into_file is not supported on Windows");
66287     return;
66288   }
66289 #endif
66290 
66291   protos::gen::EnableTracingRequest req;
66292   *req.mutable_trace_config() = trace_config;
66293   ipc::Deferred<protos::gen::EnableTracingResponse> async_response;
66294   auto weak_this = weak_ptr_factory_.GetWeakPtr();
66295   async_response.Bind(
66296       [weak_this](
66297           ipc::AsyncResult<protos::gen::EnableTracingResponse> response) {
66298         if (weak_this)
66299           weak_this->OnEnableTracingResponse(std::move(response));
66300       });
66301 
66302   // |fd| will be closed when this function returns, but it's fine because the
66303   // IPC layer dup()'s it when sending the IPC.
66304   consumer_port_.EnableTracing(req, std::move(async_response), *fd);
66305 }
66306 
ChangeTraceConfig(const TraceConfig & trace_config)66307 void ConsumerIPCClientImpl::ChangeTraceConfig(const TraceConfig& trace_config) {
66308   if (!connected_) {
66309     PERFETTO_DLOG(
66310         "Cannot ChangeTraceConfig(), not connected to tracing service");
66311     return;
66312   }
66313 
66314   ipc::Deferred<protos::gen::ChangeTraceConfigResponse> async_response;
66315   async_response.Bind(
66316       [](ipc::AsyncResult<protos::gen::ChangeTraceConfigResponse> response) {
66317         if (!response)
66318           PERFETTO_DLOG("ChangeTraceConfig() failed");
66319       });
66320   protos::gen::ChangeTraceConfigRequest req;
66321   *req.mutable_trace_config() = trace_config;
66322   consumer_port_.ChangeTraceConfig(req, std::move(async_response));
66323 }
66324 
StartTracing()66325 void ConsumerIPCClientImpl::StartTracing() {
66326   if (!connected_) {
66327     PERFETTO_DLOG("Cannot StartTracing(), not connected to tracing service");
66328     return;
66329   }
66330 
66331   ipc::Deferred<protos::gen::StartTracingResponse> async_response;
66332   async_response.Bind(
66333       [](ipc::AsyncResult<protos::gen::StartTracingResponse> response) {
66334         if (!response)
66335           PERFETTO_DLOG("StartTracing() failed");
66336       });
66337   protos::gen::StartTracingRequest req;
66338   consumer_port_.StartTracing(req, std::move(async_response));
66339 }
66340 
DisableTracing()66341 void ConsumerIPCClientImpl::DisableTracing() {
66342   if (!connected_) {
66343     PERFETTO_DLOG("Cannot DisableTracing(), not connected to tracing service");
66344     return;
66345   }
66346 
66347   ipc::Deferred<protos::gen::DisableTracingResponse> async_response;
66348   async_response.Bind(
66349       [](ipc::AsyncResult<protos::gen::DisableTracingResponse> response) {
66350         if (!response)
66351           PERFETTO_DLOG("DisableTracing() failed");
66352       });
66353   consumer_port_.DisableTracing(protos::gen::DisableTracingRequest(),
66354                                 std::move(async_response));
66355 }
66356 
ReadBuffers()66357 void ConsumerIPCClientImpl::ReadBuffers() {
66358   if (!connected_) {
66359     PERFETTO_DLOG("Cannot ReadBuffers(), not connected to tracing service");
66360     return;
66361   }
66362 
66363   ipc::Deferred<protos::gen::ReadBuffersResponse> async_response;
66364 
66365   // The IPC layer guarantees that callbacks are destroyed after this object
66366   // is destroyed (by virtue of destroying the |consumer_port_|). In turn the
66367   // contract of this class expects the caller to not destroy the Consumer class
66368   // before having destroyed this class. Hence binding |this| here is safe.
66369   async_response.Bind(
66370       [this](ipc::AsyncResult<protos::gen::ReadBuffersResponse> response) {
66371         OnReadBuffersResponse(std::move(response));
66372       });
66373   consumer_port_.ReadBuffers(protos::gen::ReadBuffersRequest(),
66374                              std::move(async_response));
66375 }
66376 
OnReadBuffersResponse(ipc::AsyncResult<protos::gen::ReadBuffersResponse> response)66377 void ConsumerIPCClientImpl::OnReadBuffersResponse(
66378     ipc::AsyncResult<protos::gen::ReadBuffersResponse> response) {
66379   if (!response) {
66380     PERFETTO_DLOG("ReadBuffers() failed");
66381     return;
66382   }
66383   std::vector<TracePacket> trace_packets;
66384   for (auto& resp_slice : response->slices()) {
66385     const std::string& slice_data = resp_slice.data();
66386     Slice slice = Slice::Allocate(slice_data.size());
66387     memcpy(slice.own_data(), slice_data.data(), slice.size);
66388     partial_packet_.AddSlice(std::move(slice));
66389     if (resp_slice.last_slice_for_packet())
66390       trace_packets.emplace_back(std::move(partial_packet_));
66391   }
66392   if (!trace_packets.empty() || !response.has_more())
66393     consumer_->OnTraceData(std::move(trace_packets), response.has_more());
66394 }
66395 
OnEnableTracingResponse(ipc::AsyncResult<protos::gen::EnableTracingResponse> response)66396 void ConsumerIPCClientImpl::OnEnableTracingResponse(
66397     ipc::AsyncResult<protos::gen::EnableTracingResponse> response) {
66398   std::string error;
66399   // |response| might be empty when the request gets rejected (if the connection
66400   // with the service is dropped all outstanding requests are auto-rejected).
66401   if (!response) {
66402     error =
66403         "EnableTracing IPC request rejected. This is likely due to a loss of "
66404         "the traced connection";
66405   } else {
66406     error = response->error();
66407   }
66408   if (!response || response->disabled())
66409     consumer_->OnTracingDisabled(error);
66410 }
66411 
FreeBuffers()66412 void ConsumerIPCClientImpl::FreeBuffers() {
66413   if (!connected_) {
66414     PERFETTO_DLOG("Cannot FreeBuffers(), not connected to tracing service");
66415     return;
66416   }
66417 
66418   protos::gen::FreeBuffersRequest req;
66419   ipc::Deferred<protos::gen::FreeBuffersResponse> async_response;
66420   async_response.Bind(
66421       [](ipc::AsyncResult<protos::gen::FreeBuffersResponse> response) {
66422         if (!response)
66423           PERFETTO_DLOG("FreeBuffers() failed");
66424       });
66425   consumer_port_.FreeBuffers(req, std::move(async_response));
66426 }
66427 
Flush(uint32_t timeout_ms,FlushCallback callback)66428 void ConsumerIPCClientImpl::Flush(uint32_t timeout_ms, FlushCallback callback) {
66429   if (!connected_) {
66430     PERFETTO_DLOG("Cannot Flush(), not connected to tracing service");
66431     return callback(/*success=*/false);
66432   }
66433 
66434   protos::gen::FlushRequest req;
66435   req.set_timeout_ms(static_cast<uint32_t>(timeout_ms));
66436   ipc::Deferred<protos::gen::FlushResponse> async_response;
66437   async_response.Bind(
66438       [callback](ipc::AsyncResult<protos::gen::FlushResponse> response) {
66439         callback(!!response);
66440       });
66441   consumer_port_.Flush(req, std::move(async_response));
66442 }
66443 
Detach(const std::string & key)66444 void ConsumerIPCClientImpl::Detach(const std::string& key) {
66445   if (!connected_) {
66446     PERFETTO_DLOG("Cannot Detach(), not connected to tracing service");
66447     return;
66448   }
66449 
66450   protos::gen::DetachRequest req;
66451   req.set_key(key);
66452   ipc::Deferred<protos::gen::DetachResponse> async_response;
66453   auto weak_this = weak_ptr_factory_.GetWeakPtr();
66454 
66455   async_response.Bind(
66456       [weak_this](ipc::AsyncResult<protos::gen::DetachResponse> response) {
66457         if (weak_this)
66458           weak_this->consumer_->OnDetach(!!response);
66459       });
66460   consumer_port_.Detach(req, std::move(async_response));
66461 }
66462 
Attach(const std::string & key)66463 void ConsumerIPCClientImpl::Attach(const std::string& key) {
66464   if (!connected_) {
66465     PERFETTO_DLOG("Cannot Attach(), not connected to tracing service");
66466     return;
66467   }
66468 
66469   {
66470     protos::gen::AttachRequest req;
66471     req.set_key(key);
66472     ipc::Deferred<protos::gen::AttachResponse> async_response;
66473     auto weak_this = weak_ptr_factory_.GetWeakPtr();
66474 
66475     async_response.Bind(
66476         [weak_this](ipc::AsyncResult<protos::gen::AttachResponse> response) {
66477           if (!weak_this)
66478             return;
66479           if (!response) {
66480             weak_this->consumer_->OnAttach(/*success=*/false, TraceConfig());
66481             return;
66482           }
66483           const TraceConfig& trace_config = response->trace_config();
66484 
66485           // If attached succesfully, also attach to the end-of-trace
66486           // notificaton callback, via EnableTracing(attach_notification_only).
66487           protos::gen::EnableTracingRequest enable_req;
66488           enable_req.set_attach_notification_only(true);
66489           ipc::Deferred<protos::gen::EnableTracingResponse> enable_resp;
66490           enable_resp.Bind(
66491               [weak_this](
66492                   ipc::AsyncResult<protos::gen::EnableTracingResponse> resp) {
66493                 if (weak_this)
66494                   weak_this->OnEnableTracingResponse(std::move(resp));
66495               });
66496           weak_this->consumer_port_.EnableTracing(enable_req,
66497                                                   std::move(enable_resp));
66498 
66499           weak_this->consumer_->OnAttach(/*success=*/true, trace_config);
66500         });
66501     consumer_port_.Attach(req, std::move(async_response));
66502   }
66503 }
66504 
GetTraceStats()66505 void ConsumerIPCClientImpl::GetTraceStats() {
66506   if (!connected_) {
66507     PERFETTO_DLOG("Cannot GetTraceStats(), not connected to tracing service");
66508     return;
66509   }
66510 
66511   protos::gen::GetTraceStatsRequest req;
66512   ipc::Deferred<protos::gen::GetTraceStatsResponse> async_response;
66513 
66514   // The IPC layer guarantees that callbacks are destroyed after this object
66515   // is destroyed (by virtue of destroying the |consumer_port_|). In turn the
66516   // contract of this class expects the caller to not destroy the Consumer class
66517   // before having destroyed this class. Hence binding |this| here is safe.
66518   async_response.Bind(
66519       [this](ipc::AsyncResult<protos::gen::GetTraceStatsResponse> response) {
66520         if (!response) {
66521           consumer_->OnTraceStats(/*success=*/false, TraceStats());
66522           return;
66523         }
66524         consumer_->OnTraceStats(/*success=*/true, response->trace_stats());
66525       });
66526   consumer_port_.GetTraceStats(req, std::move(async_response));
66527 }
66528 
ObserveEvents(uint32_t enabled_event_types)66529 void ConsumerIPCClientImpl::ObserveEvents(uint32_t enabled_event_types) {
66530   if (!connected_) {
66531     PERFETTO_DLOG("Cannot ObserveEvents(), not connected to tracing service");
66532     return;
66533   }
66534 
66535   protos::gen::ObserveEventsRequest req;
66536   for (uint32_t i = 0; i < 32; i++) {
66537     const uint32_t event_id = 1u << i;
66538     if (enabled_event_types & event_id)
66539       req.add_events_to_observe(static_cast<ObservableEvents::Type>(event_id));
66540   }
66541 
66542   ipc::Deferred<protos::gen::ObserveEventsResponse> async_response;
66543   // The IPC layer guarantees that callbacks are destroyed after this object
66544   // is destroyed (by virtue of destroying the |consumer_port_|). In turn the
66545   // contract of this class expects the caller to not destroy the Consumer class
66546   // before having destroyed this class. Hence binding |this| here is safe.
66547   async_response.Bind(
66548       [this](ipc::AsyncResult<protos::gen::ObserveEventsResponse> response) {
66549         // Skip empty response, which the service sends to close the stream.
66550         if (!response.has_more()) {
66551           PERFETTO_DCHECK(!response.success());
66552           return;
66553         }
66554         consumer_->OnObservableEvents(response->events());
66555       });
66556   consumer_port_.ObserveEvents(req, std::move(async_response));
66557 }
66558 
QueryServiceState(QueryServiceStateCallback callback)66559 void ConsumerIPCClientImpl::QueryServiceState(
66560     QueryServiceStateCallback callback) {
66561   if (!connected_) {
66562     PERFETTO_DLOG(
66563         "Cannot QueryServiceState(), not connected to tracing service");
66564     return;
66565   }
66566 
66567   auto it = pending_query_svc_reqs_.insert(pending_query_svc_reqs_.end(),
66568                                            {std::move(callback), {}});
66569   protos::gen::QueryServiceStateRequest req;
66570   ipc::Deferred<protos::gen::QueryServiceStateResponse> async_response;
66571   auto weak_this = weak_ptr_factory_.GetWeakPtr();
66572   async_response.Bind(
66573       [weak_this,
66574        it](ipc::AsyncResult<protos::gen::QueryServiceStateResponse> response) {
66575         if (weak_this)
66576           weak_this->OnQueryServiceStateResponse(std::move(response), it);
66577       });
66578   consumer_port_.QueryServiceState(req, std::move(async_response));
66579 }
66580 
OnQueryServiceStateResponse(ipc::AsyncResult<protos::gen::QueryServiceStateResponse> response,PendingQueryServiceRequests::iterator req_it)66581 void ConsumerIPCClientImpl::OnQueryServiceStateResponse(
66582     ipc::AsyncResult<protos::gen::QueryServiceStateResponse> response,
66583     PendingQueryServiceRequests::iterator req_it) {
66584   PERFETTO_DCHECK(req_it->callback);
66585 
66586   if (!response) {
66587     auto callback = std::move(req_it->callback);
66588     pending_query_svc_reqs_.erase(req_it);
66589     callback(false, TracingServiceState());
66590     return;
66591   }
66592 
66593   // The QueryServiceState response can be split in several chunks if the
66594   // service has several data sources. The client is supposed to merge all the
66595   // replies. The easiest way to achieve this is to re-serialize the partial
66596   // response and then re-decode the merged result in one shot.
66597   std::vector<uint8_t>& merged_resp = req_it->merged_resp;
66598   std::vector<uint8_t> part = response->service_state().SerializeAsArray();
66599   merged_resp.insert(merged_resp.end(), part.begin(), part.end());
66600 
66601   if (response.has_more())
66602     return;
66603 
66604   // All replies have been received. Decode the merged result and reply to the
66605   // callback.
66606   protos::gen::TracingServiceState svc_state;
66607   bool ok = svc_state.ParseFromArray(merged_resp.data(), merged_resp.size());
66608   if (!ok)
66609     PERFETTO_ELOG("Failed to decode merged QueryServiceStateResponse");
66610   auto callback = std::move(req_it->callback);
66611   pending_query_svc_reqs_.erase(req_it);
66612   callback(ok, std::move(svc_state));
66613 }
66614 
QueryCapabilities(QueryCapabilitiesCallback callback)66615 void ConsumerIPCClientImpl::QueryCapabilities(
66616     QueryCapabilitiesCallback callback) {
66617   if (!connected_) {
66618     PERFETTO_DLOG(
66619         "Cannot QueryCapabilities(), not connected to tracing service");
66620     return;
66621   }
66622 
66623   protos::gen::QueryCapabilitiesRequest req;
66624   ipc::Deferred<protos::gen::QueryCapabilitiesResponse> async_response;
66625   async_response.Bind(
66626       [callback](
66627           ipc::AsyncResult<protos::gen::QueryCapabilitiesResponse> response) {
66628         if (!response) {
66629           // If the IPC fails, we are talking to an older version of the service
66630           // that didn't support QueryCapabilities at all. In this case return
66631           // an empty capabilities message.
66632           callback(TracingServiceCapabilities());
66633         } else {
66634           callback(response->capabilities());
66635         }
66636       });
66637   consumer_port_.QueryCapabilities(req, std::move(async_response));
66638 }
66639 
SaveTraceForBugreport(SaveTraceForBugreportCallback callback)66640 void ConsumerIPCClientImpl::SaveTraceForBugreport(
66641     SaveTraceForBugreportCallback callback) {
66642   if (!connected_) {
66643     PERFETTO_DLOG(
66644         "Cannot SaveTraceForBugreport(), not connected to tracing service");
66645     return;
66646   }
66647 
66648   protos::gen::SaveTraceForBugreportRequest req;
66649   ipc::Deferred<protos::gen::SaveTraceForBugreportResponse> async_response;
66650   async_response.Bind(
66651       [callback](ipc::AsyncResult<protos::gen::SaveTraceForBugreportResponse>
66652                      response) {
66653         if (!response) {
66654           // If the IPC fails, we are talking to an older version of the service
66655           // that didn't support SaveTraceForBugreport at all.
66656           callback(
66657               false,
66658               "The tracing service doesn't support SaveTraceForBugreport()");
66659         } else {
66660           callback(response->success(), response->msg());
66661         }
66662       });
66663   consumer_port_.SaveTraceForBugreport(req, std::move(async_response));
66664 }
66665 
66666 }  // namespace perfetto
66667 // gen_amalgamated begin source: src/tracing/ipc/producer/producer_ipc_client_impl.cc
66668 // gen_amalgamated begin header: src/tracing/ipc/producer/producer_ipc_client_impl.h
66669 // gen_amalgamated begin header: include/perfetto/ext/tracing/ipc/producer_ipc_client.h
66670 /*
66671  * Copyright (C) 2017 The Android Open Source Project
66672  *
66673  * Licensed under the Apache License, Version 2.0 (the "License");
66674  * you may not use this file except in compliance with the License.
66675  * You may obtain a copy of the License at
66676  *
66677  *      http://www.apache.org/licenses/LICENSE-2.0
66678  *
66679  * Unless required by applicable law or agreed to in writing, software
66680  * distributed under the License is distributed on an "AS IS" BASIS,
66681  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66682  * See the License for the specific language governing permissions and
66683  * limitations under the License.
66684  */
66685 
66686 #ifndef INCLUDE_PERFETTO_EXT_TRACING_IPC_PRODUCER_IPC_CLIENT_H_
66687 #define INCLUDE_PERFETTO_EXT_TRACING_IPC_PRODUCER_IPC_CLIENT_H_
66688 
66689 #include <memory>
66690 #include <string>
66691 
66692 // gen_amalgamated expanded: #include "perfetto/base/export.h"
66693 // gen_amalgamated expanded: #include "perfetto/ext/ipc/client.h"
66694 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
66695 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
66696 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
66697 
66698 namespace perfetto {
66699 
66700 class Producer;
66701 
66702 // Allows to connect to a remote Service through a UNIX domain socket.
66703 // Exposed to:
66704 //   Producer(s) of the tracing library.
66705 // Implemented in:
66706 //   src/tracing/ipc/producer/producer_ipc_client_impl.cc
66707 class PERFETTO_EXPORT ProducerIPCClient {
66708  public:
66709   enum class ConnectionFlags {
66710     // Fails immediately with OnConnect(false) if the service connection cannot
66711     // be established.
66712     kDefault = 0,
66713 
66714     // Keeps retrying with exponential backoff indefinitely. The caller will
66715     // never see an OnConnect(false).
66716     kRetryIfUnreachable = 1,
66717   };
66718 
66719   // Connects to the producer port of the Service listening on the given
66720   // |service_sock_name|. If the connection is successful, the OnConnect()
66721   // method will be invoked asynchronously on the passed Producer interface. If
66722   // the connection fails, OnDisconnect() will be invoked instead. The returned
66723   // ProducerEndpoint serves also to delimit the scope of the callbacks invoked
66724   // on the Producer interface: no more Producer callbacks are invoked
66725   // immediately after its destruction and any pending callback will be dropped.
66726   // To provide a producer-allocated shared memory buffer, both |shm| and
66727   // |shm_arbiter| should be set. |shm_arbiter| should be an unbound
66728   // SharedMemoryArbiter instance. When |shm| and |shm_arbiter| are provided,
66729   // the service will attempt to adopt the provided SMB. If this fails, the
66730   // ProducerEndpoint will disconnect, but the SMB and arbiter will remain valid
66731   // until the client is destroyed.
66732   //
66733   // TODO(eseckler): Support adoption failure more gracefully.
66734   // TODO(primiano): move all the existing use cases to the Connect(ConnArgs)
66735   // below. Also move the functionality of ConnectionFlags into ConnArgs.
66736   static std::unique_ptr<TracingService::ProducerEndpoint> Connect(
66737       const char* service_sock_name,
66738       Producer*,
66739       const std::string& producer_name,
66740       base::TaskRunner*,
66741       TracingService::ProducerSMBScrapingMode smb_scraping_mode =
66742           TracingService::ProducerSMBScrapingMode::kDefault,
66743       size_t shared_memory_size_hint_bytes = 0,
66744       size_t shared_memory_page_size_hint_bytes = 0,
66745       std::unique_ptr<SharedMemory> shm = nullptr,
66746       std::unique_ptr<SharedMemoryArbiter> shm_arbiter = nullptr,
66747       ConnectionFlags = ConnectionFlags::kDefault);
66748 
66749   // Overload of Connect() to support adopting a connected socket using
66750   // ipc::Client::ConnArgs.
66751   static std::unique_ptr<TracingService::ProducerEndpoint> Connect(
66752       ipc::Client::ConnArgs,
66753       Producer*,
66754       const std::string& producer_name,
66755       base::TaskRunner*,
66756       TracingService::ProducerSMBScrapingMode smb_scraping_mode =
66757           TracingService::ProducerSMBScrapingMode::kDefault,
66758       size_t shared_memory_size_hint_bytes = 0,
66759       size_t shared_memory_page_size_hint_bytes = 0,
66760       std::unique_ptr<SharedMemory> shm = nullptr,
66761       std::unique_ptr<SharedMemoryArbiter> shm_arbiter = nullptr);
66762 
66763  protected:
66764   ProducerIPCClient() = delete;
66765 };
66766 
66767 }  // namespace perfetto
66768 
66769 #endif  // INCLUDE_PERFETTO_EXT_TRACING_IPC_PRODUCER_IPC_CLIENT_H_
66770 /*
66771  * Copyright (C) 2017 The Android Open Source Project
66772  *
66773  * Licensed under the Apache License, Version 2.0 (the "License");
66774  * you may not use this file except in compliance with the License.
66775  * You may obtain a copy of the License at
66776  *
66777  *      http://www.apache.org/licenses/LICENSE-2.0
66778  *
66779  * Unless required by applicable law or agreed to in writing, software
66780  * distributed under the License is distributed on an "AS IS" BASIS,
66781  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66782  * See the License for the specific language governing permissions and
66783  * limitations under the License.
66784  */
66785 
66786 #ifndef SRC_TRACING_IPC_PRODUCER_PRODUCER_IPC_CLIENT_IMPL_H_
66787 #define SRC_TRACING_IPC_PRODUCER_PRODUCER_IPC_CLIENT_IMPL_H_
66788 
66789 #include <stdint.h>
66790 
66791 #include <set>
66792 #include <vector>
66793 
66794 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
66795 // gen_amalgamated expanded: #include "perfetto/ext/ipc/client.h"
66796 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
66797 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
66798 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
66799 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
66800 // gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/producer_ipc_client.h"
66801 
66802 // gen_amalgamated expanded: #include "protos/perfetto/ipc/producer_port.ipc.h"
66803 
66804 namespace perfetto {
66805 
66806 namespace base {
66807 class TaskRunner;
66808 }  // namespace base
66809 
66810 class Producer;
66811 class SharedMemoryArbiter;
66812 
66813 // Exposes a Service endpoint to Producer(s), proxying all requests through a
66814 // IPC channel to the remote Service. This class is the glue layer between the
66815 // generic Service interface exposed to the clients of the library and the
66816 // actual IPC transport.
66817 class ProducerIPCClientImpl : public TracingService::ProducerEndpoint,
66818                               public ipc::ServiceProxy::EventListener {
66819  public:
66820   ProducerIPCClientImpl(ipc::Client::ConnArgs,
66821                         Producer*,
66822                         const std::string& producer_name,
66823                         base::TaskRunner*,
66824                         TracingService::ProducerSMBScrapingMode,
66825                         size_t shared_memory_size_hint_bytes,
66826                         size_t shared_memory_page_size_hint_bytes,
66827                         std::unique_ptr<SharedMemory> shm,
66828                         std::unique_ptr<SharedMemoryArbiter> shm_arbiter);
66829   ~ProducerIPCClientImpl() override;
66830 
66831   // TracingService::ProducerEndpoint implementation.
66832   // These methods are invoked by the actual Producer(s) code by clients of the
66833   // tracing library, which know nothing about the IPC transport.
66834   void RegisterDataSource(const DataSourceDescriptor&) override;
66835   void UnregisterDataSource(const std::string& name) override;
66836   void RegisterTraceWriter(uint32_t writer_id, uint32_t target_buffer) override;
66837   void UnregisterTraceWriter(uint32_t writer_id) override;
66838   void CommitData(const CommitDataRequest&, CommitDataCallback) override;
66839   void NotifyDataSourceStarted(DataSourceInstanceID) override;
66840   void NotifyDataSourceStopped(DataSourceInstanceID) override;
66841   void ActivateTriggers(const std::vector<std::string>&) override;
66842   void Sync(std::function<void()> callback) override;
66843 
66844   std::unique_ptr<TraceWriter> CreateTraceWriter(
66845       BufferID target_buffer,
66846       BufferExhaustedPolicy) override;
66847   SharedMemoryArbiter* MaybeSharedMemoryArbiter() override;
66848   bool IsShmemProvidedByProducer() const override;
66849   void NotifyFlushComplete(FlushRequestID) override;
66850   SharedMemory* shared_memory() const override;
66851   size_t shared_buffer_page_size_kb() const override;
66852 
66853   // ipc::ServiceProxy::EventListener implementation.
66854   // These methods are invoked by the IPC layer, which knows nothing about
66855   // tracing, producers and consumers.
66856   void OnConnect() override;
66857   void OnDisconnect() override;
66858 
GetClientForTesting()66859   ipc::Client* GetClientForTesting() { return ipc_channel_.get(); }
66860 
66861  private:
66862   // Invoked soon after having established the connection with the service.
66863   void OnConnectionInitialized(bool connection_succeeded,
66864                                bool using_shmem_provided_by_producer,
66865                                bool direct_smb_patching_supported);
66866 
66867   // Invoked when the remote Service sends an IPC to tell us to do something
66868   // (e.g. start/stop a data source).
66869   void OnServiceRequest(const protos::gen::GetAsyncCommandResponse&);
66870 
66871   // TODO think to destruction order, do we rely on any specific dtor sequence?
66872   Producer* const producer_;
66873   base::TaskRunner* const task_runner_;
66874 
66875   // The object that owns the client socket and takes care of IPC traffic.
66876   std::unique_ptr<ipc::Client> ipc_channel_;
66877 
66878   // The proxy interface for the producer port of the service. It is bound
66879   // to |ipc_channel_| and (de)serializes method invocations over the wire.
66880   protos::gen::ProducerPortProxy producer_port_;
66881 
66882   std::unique_ptr<SharedMemory> shared_memory_;
66883   std::unique_ptr<SharedMemoryArbiter> shared_memory_arbiter_;
66884   size_t shared_buffer_page_size_kb_ = 0;
66885   std::set<DataSourceInstanceID> data_sources_setup_;
66886   bool connected_ = false;
66887   std::string const name_;
66888   size_t shared_memory_page_size_hint_bytes_ = 0;
66889   size_t shared_memory_size_hint_bytes_ = 0;
66890   TracingService::ProducerSMBScrapingMode const smb_scraping_mode_;
66891   bool is_shmem_provided_by_producer_ = false;
66892   bool direct_smb_patching_supported_ = false;
66893   std::vector<std::function<void()>> pending_sync_reqs_;
66894   PERFETTO_THREAD_CHECKER(thread_checker_)
66895 };
66896 
66897 }  // namespace perfetto
66898 
66899 #endif  // SRC_TRACING_IPC_PRODUCER_PRODUCER_IPC_CLIENT_IMPL_H_
66900 /*
66901  * Copyright (C) 2017 The Android Open Source Project
66902  *
66903  * Licensed under the Apache License, Version 2.0 (the "License");
66904  * you may not use this file except in compliance with the License.
66905  * You may obtain a copy of the License at
66906  *
66907  *      http://www.apache.org/licenses/LICENSE-2.0
66908  *
66909  * Unless required by applicable law or agreed to in writing, software
66910  * distributed under the License is distributed on an "AS IS" BASIS,
66911  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66912  * See the License for the specific language governing permissions and
66913  * limitations under the License.
66914  */
66915 
66916 // gen_amalgamated expanded: #include "src/tracing/ipc/producer/producer_ipc_client_impl.h"
66917 
66918 #include <inttypes.h>
66919 #include <string.h>
66920 
66921 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
66922 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
66923 // gen_amalgamated expanded: #include "perfetto/ext/base/version.h"
66924 // gen_amalgamated expanded: #include "perfetto/ext/ipc/client.h"
66925 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/commit_data_request.h"
66926 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
66927 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
66928 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
66929 // gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
66930 // gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
66931 // gen_amalgamated expanded: #include "perfetto/tracing/core/trace_config.h"
66932 // gen_amalgamated expanded: #include "src/tracing/ipc/posix_shared_memory.h"
66933 
66934 // TODO(fmayer): think to what happens when ProducerIPCClientImpl gets destroyed
66935 // w.r.t. the Producer pointer. Also think to lifetime of the Producer* during
66936 // the callbacks.
66937 
66938 namespace perfetto {
66939 
66940 // 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)66941 std::unique_ptr<TracingService::ProducerEndpoint> ProducerIPCClient::Connect(
66942     const char* service_sock_name,
66943     Producer* producer,
66944     const std::string& producer_name,
66945     base::TaskRunner* task_runner,
66946     TracingService::ProducerSMBScrapingMode smb_scraping_mode,
66947     size_t shared_memory_size_hint_bytes,
66948     size_t shared_memory_page_size_hint_bytes,
66949     std::unique_ptr<SharedMemory> shm,
66950     std::unique_ptr<SharedMemoryArbiter> shm_arbiter,
66951     ConnectionFlags conn_flags) {
66952   return std::unique_ptr<TracingService::ProducerEndpoint>(
66953       new ProducerIPCClientImpl(
66954           {service_sock_name,
66955            conn_flags ==
66956                ProducerIPCClient::ConnectionFlags::kRetryIfUnreachable},
66957           producer, producer_name, task_runner, smb_scraping_mode,
66958           shared_memory_size_hint_bytes, shared_memory_page_size_hint_bytes,
66959           std::move(shm), std::move(shm_arbiter)));
66960 }
66961 
66962 // static. (Declared in include/tracing/ipc/producer_ipc_client.h).
Connect(ipc::Client::ConnArgs conn_args,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)66963 std::unique_ptr<TracingService::ProducerEndpoint> ProducerIPCClient::Connect(
66964     ipc::Client::ConnArgs conn_args,
66965     Producer* producer,
66966     const std::string& producer_name,
66967     base::TaskRunner* task_runner,
66968     TracingService::ProducerSMBScrapingMode smb_scraping_mode,
66969     size_t shared_memory_size_hint_bytes,
66970     size_t shared_memory_page_size_hint_bytes,
66971     std::unique_ptr<SharedMemory> shm,
66972     std::unique_ptr<SharedMemoryArbiter> shm_arbiter) {
66973   return std::unique_ptr<TracingService::ProducerEndpoint>(
66974       new ProducerIPCClientImpl(std::move(conn_args), producer, producer_name,
66975                                 task_runner, smb_scraping_mode,
66976                                 shared_memory_size_hint_bytes,
66977                                 shared_memory_page_size_hint_bytes,
66978                                 std::move(shm), std::move(shm_arbiter)));
66979 }
66980 
ProducerIPCClientImpl(ipc::Client::ConnArgs conn_args,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)66981 ProducerIPCClientImpl::ProducerIPCClientImpl(
66982     ipc::Client::ConnArgs conn_args,
66983     Producer* producer,
66984     const std::string& producer_name,
66985     base::TaskRunner* task_runner,
66986     TracingService::ProducerSMBScrapingMode smb_scraping_mode,
66987     size_t shared_memory_size_hint_bytes,
66988     size_t shared_memory_page_size_hint_bytes,
66989     std::unique_ptr<SharedMemory> shm,
66990     std::unique_ptr<SharedMemoryArbiter> shm_arbiter)
66991     : producer_(producer),
66992       task_runner_(task_runner),
66993       ipc_channel_(
66994           ipc::Client::CreateInstance(std::move(conn_args), task_runner)),
66995       producer_port_(this /* event_listener */),
66996       shared_memory_(std::move(shm)),
66997       shared_memory_arbiter_(std::move(shm_arbiter)),
66998       name_(producer_name),
66999       shared_memory_page_size_hint_bytes_(shared_memory_page_size_hint_bytes),
67000       shared_memory_size_hint_bytes_(shared_memory_size_hint_bytes),
67001       smb_scraping_mode_(smb_scraping_mode) {
67002   // Check for producer-provided SMB (used by Chrome for startup tracing).
67003   if (shared_memory_) {
67004     // We also expect a valid (unbound) arbiter. Bind it to this endpoint now.
67005     PERFETTO_CHECK(shared_memory_arbiter_);
67006     shared_memory_arbiter_->BindToProducerEndpoint(this, task_runner_);
67007 
67008     // If the service accepts our SMB, then it must match our requested page
67009     // layout. The protocol doesn't allow the service to change the size and
67010     // layout when the SMB is provided by the producer.
67011     shared_buffer_page_size_kb_ = shared_memory_page_size_hint_bytes_ / 1024;
67012   }
67013 
67014   ipc_channel_->BindService(producer_port_.GetWeakPtr());
67015   PERFETTO_DCHECK_THREAD(thread_checker_);
67016 }
67017 
~ProducerIPCClientImpl()67018 ProducerIPCClientImpl::~ProducerIPCClientImpl() {
67019   PERFETTO_DCHECK_THREAD(thread_checker_);
67020 }
67021 
67022 // Called by the IPC layer if the BindService() succeeds.
OnConnect()67023 void ProducerIPCClientImpl::OnConnect() {
67024   PERFETTO_DCHECK_THREAD(thread_checker_);
67025   connected_ = true;
67026 
67027   // The IPC layer guarantees that any outstanding callback will be dropped on
67028   // the floor if producer_port_ is destroyed between the request and the reply.
67029   // Binding |this| is hence safe.
67030   ipc::Deferred<protos::gen::InitializeConnectionResponse> on_init;
67031   on_init.Bind(
67032       [this](ipc::AsyncResult<protos::gen::InitializeConnectionResponse> resp) {
67033         OnConnectionInitialized(
67034             resp.success(),
67035             resp.success() ? resp->using_shmem_provided_by_producer() : false,
67036             resp.success() ? resp->direct_smb_patching_supported() : false);
67037       });
67038   protos::gen::InitializeConnectionRequest req;
67039   req.set_producer_name(name_);
67040   req.set_shared_memory_size_hint_bytes(
67041       static_cast<uint32_t>(shared_memory_size_hint_bytes_));
67042   req.set_shared_memory_page_size_hint_bytes(
67043       static_cast<uint32_t>(shared_memory_page_size_hint_bytes_));
67044   switch (smb_scraping_mode_) {
67045     case TracingService::ProducerSMBScrapingMode::kDefault:
67046       // No need to set the mode, it defaults to use the service default if
67047       // unspecified.
67048       break;
67049     case TracingService::ProducerSMBScrapingMode::kEnabled:
67050       req.set_smb_scraping_mode(
67051           protos::gen::InitializeConnectionRequest::SMB_SCRAPING_ENABLED);
67052       break;
67053     case TracingService::ProducerSMBScrapingMode::kDisabled:
67054       req.set_smb_scraping_mode(
67055           protos::gen::InitializeConnectionRequest::SMB_SCRAPING_DISABLED);
67056       break;
67057   }
67058 
67059   int shm_fd = -1;
67060   if (shared_memory_) {
67061     shm_fd = static_cast<PosixSharedMemory*>(shared_memory_.get())->fd();
67062     req.set_producer_provided_shmem(true);
67063   }
67064 
67065 #if PERFETTO_DCHECK_IS_ON()
67066   req.set_build_flags(
67067       protos::gen::InitializeConnectionRequest::BUILD_FLAGS_DCHECKS_ON);
67068 #else
67069   req.set_build_flags(
67070       protos::gen::InitializeConnectionRequest::BUILD_FLAGS_DCHECKS_OFF);
67071 #endif
67072   req.set_sdk_version(base::GetVersionString());
67073   producer_port_.InitializeConnection(req, std::move(on_init), shm_fd);
67074 
67075   // Create the back channel to receive commands from the Service.
67076   ipc::Deferred<protos::gen::GetAsyncCommandResponse> on_cmd;
67077   on_cmd.Bind(
67078       [this](ipc::AsyncResult<protos::gen::GetAsyncCommandResponse> resp) {
67079         if (!resp)
67080           return;  // The IPC channel was closed and |resp| was auto-rejected.
67081         OnServiceRequest(*resp);
67082       });
67083   producer_port_.GetAsyncCommand(protos::gen::GetAsyncCommandRequest(),
67084                                  std::move(on_cmd));
67085 
67086   // If there are pending Sync() requests, send them now.
67087   for (const auto& pending_sync : pending_sync_reqs_)
67088     Sync(std::move(pending_sync));
67089   pending_sync_reqs_.clear();
67090 }
67091 
OnDisconnect()67092 void ProducerIPCClientImpl::OnDisconnect() {
67093   PERFETTO_DCHECK_THREAD(thread_checker_);
67094   PERFETTO_DLOG("Tracing service connection failure");
67095   connected_ = false;
67096   data_sources_setup_.clear();
67097   producer_->OnDisconnect();  // Note: may delete |this|.
67098 }
67099 
OnConnectionInitialized(bool connection_succeeded,bool using_shmem_provided_by_producer,bool direct_smb_patching_supported)67100 void ProducerIPCClientImpl::OnConnectionInitialized(
67101     bool connection_succeeded,
67102     bool using_shmem_provided_by_producer,
67103     bool direct_smb_patching_supported) {
67104   PERFETTO_DCHECK_THREAD(thread_checker_);
67105   // If connection_succeeded == false, the OnDisconnect() call will follow next
67106   // and there we'll notify the |producer_|. TODO: add a test for this.
67107   if (!connection_succeeded)
67108     return;
67109   is_shmem_provided_by_producer_ = using_shmem_provided_by_producer;
67110   direct_smb_patching_supported_ = direct_smb_patching_supported;
67111   producer_->OnConnect();
67112 
67113   // Bail out if the service failed to adopt our producer-allocated SMB.
67114   // TODO(eseckler): Handle adoption failure more gracefully.
67115   if (shared_memory_ && !is_shmem_provided_by_producer_) {
67116     PERFETTO_DLOG("Service failed adopt producer-provided SMB, disconnecting.");
67117     ipc_channel_.reset();
67118     return;
67119   }
67120 }
67121 
OnServiceRequest(const protos::gen::GetAsyncCommandResponse & cmd)67122 void ProducerIPCClientImpl::OnServiceRequest(
67123     const protos::gen::GetAsyncCommandResponse& cmd) {
67124   PERFETTO_DCHECK_THREAD(thread_checker_);
67125 
67126   // This message is sent only when connecting to a service running Android Q+.
67127   // See comment below in kStartDataSource.
67128   if (cmd.has_setup_data_source()) {
67129     const auto& req = cmd.setup_data_source();
67130     const DataSourceInstanceID dsid = req.new_instance_id();
67131     data_sources_setup_.insert(dsid);
67132     producer_->SetupDataSource(dsid, req.config());
67133     return;
67134   }
67135 
67136   if (cmd.has_start_data_source()) {
67137     const auto& req = cmd.start_data_source();
67138     const DataSourceInstanceID dsid = req.new_instance_id();
67139     const DataSourceConfig& cfg = req.config();
67140     if (!data_sources_setup_.count(dsid)) {
67141       // When connecting with an older (Android P) service, the service will not
67142       // send a SetupDataSource message. We synthesize it here in that case.
67143       producer_->SetupDataSource(dsid, cfg);
67144     }
67145     producer_->StartDataSource(dsid, cfg);
67146     return;
67147   }
67148 
67149   if (cmd.has_stop_data_source()) {
67150     const DataSourceInstanceID dsid = cmd.stop_data_source().instance_id();
67151     producer_->StopDataSource(dsid);
67152     data_sources_setup_.erase(dsid);
67153     return;
67154   }
67155 
67156   if (cmd.has_setup_tracing()) {
67157     base::ScopedFile shmem_fd = ipc_channel_->TakeReceivedFD();
67158     if (shmem_fd) {
67159       // This is the nominal case used in most configurations, where the service
67160       // provides the SMB.
67161       PERFETTO_CHECK(!is_shmem_provided_by_producer_ && !shared_memory_);
67162       // TODO(primiano): handle mmap failure in case of OOM.
67163       shared_memory_ =
67164           PosixSharedMemory::AttachToFd(std::move(shmem_fd),
67165                                         /*require_seals_if_supported=*/false);
67166       shared_buffer_page_size_kb_ =
67167           cmd.setup_tracing().shared_buffer_page_size_kb();
67168       shared_memory_arbiter_ = SharedMemoryArbiter::CreateInstance(
67169           shared_memory_.get(), shared_buffer_page_size_kb_ * 1024, this,
67170           task_runner_);
67171       if (direct_smb_patching_supported_)
67172         shared_memory_arbiter_->SetDirectSMBPatchingSupportedByService();
67173     } else {
67174       // Producer-provided SMB (used by Chrome for startup tracing).
67175       PERFETTO_CHECK(is_shmem_provided_by_producer_ && shared_memory_ &&
67176                      shared_memory_arbiter_);
67177     }
67178     producer_->OnTracingSetup();
67179     return;
67180   }
67181 
67182   if (cmd.has_flush()) {
67183     // This cast boilerplate is required only because protobuf uses its own
67184     // uint64 and not stdint's uint64_t. On some 64 bit archs they differ on the
67185     // type (long vs long long) even though they have the same size.
67186     const auto* data_source_ids = cmd.flush().data_source_ids().data();
67187     static_assert(sizeof(data_source_ids[0]) == sizeof(DataSourceInstanceID),
67188                   "data_source_ids should be 64-bit");
67189     producer_->Flush(
67190         cmd.flush().request_id(),
67191         reinterpret_cast<const DataSourceInstanceID*>(data_source_ids),
67192         static_cast<size_t>(cmd.flush().data_source_ids().size()));
67193     return;
67194   }
67195 
67196   if (cmd.has_clear_incremental_state()) {
67197     const auto* data_source_ids =
67198         cmd.clear_incremental_state().data_source_ids().data();
67199     static_assert(sizeof(data_source_ids[0]) == sizeof(DataSourceInstanceID),
67200                   "data_source_ids should be 64-bit");
67201     producer_->ClearIncrementalState(
67202         reinterpret_cast<const DataSourceInstanceID*>(data_source_ids),
67203         static_cast<size_t>(
67204             cmd.clear_incremental_state().data_source_ids().size()));
67205     return;
67206   }
67207 
67208   PERFETTO_DFATAL("Unknown async request received from tracing service");
67209 }
67210 
RegisterDataSource(const DataSourceDescriptor & descriptor)67211 void ProducerIPCClientImpl::RegisterDataSource(
67212     const DataSourceDescriptor& descriptor) {
67213   PERFETTO_DCHECK_THREAD(thread_checker_);
67214   if (!connected_) {
67215     PERFETTO_DLOG(
67216         "Cannot RegisterDataSource(), not connected to tracing service");
67217   }
67218   protos::gen::RegisterDataSourceRequest req;
67219   *req.mutable_data_source_descriptor() = descriptor;
67220   ipc::Deferred<protos::gen::RegisterDataSourceResponse> async_response;
67221   async_response.Bind(
67222       [](ipc::AsyncResult<protos::gen::RegisterDataSourceResponse> response) {
67223         if (!response)
67224           PERFETTO_DLOG("RegisterDataSource() failed: connection reset");
67225       });
67226   producer_port_.RegisterDataSource(req, std::move(async_response));
67227 }
67228 
UnregisterDataSource(const std::string & name)67229 void ProducerIPCClientImpl::UnregisterDataSource(const std::string& name) {
67230   PERFETTO_DCHECK_THREAD(thread_checker_);
67231   if (!connected_) {
67232     PERFETTO_DLOG(
67233         "Cannot UnregisterDataSource(), not connected to tracing service");
67234     return;
67235   }
67236   protos::gen::UnregisterDataSourceRequest req;
67237   req.set_data_source_name(name);
67238   producer_port_.UnregisterDataSource(
67239       req, ipc::Deferred<protos::gen::UnregisterDataSourceResponse>());
67240 }
67241 
RegisterTraceWriter(uint32_t writer_id,uint32_t target_buffer)67242 void ProducerIPCClientImpl::RegisterTraceWriter(uint32_t writer_id,
67243                                                 uint32_t target_buffer) {
67244   PERFETTO_DCHECK_THREAD(thread_checker_);
67245   if (!connected_) {
67246     PERFETTO_DLOG(
67247         "Cannot RegisterTraceWriter(), not connected to tracing service");
67248     return;
67249   }
67250   protos::gen::RegisterTraceWriterRequest req;
67251   req.set_trace_writer_id(writer_id);
67252   req.set_target_buffer(target_buffer);
67253   producer_port_.RegisterTraceWriter(
67254       req, ipc::Deferred<protos::gen::RegisterTraceWriterResponse>());
67255 }
67256 
UnregisterTraceWriter(uint32_t writer_id)67257 void ProducerIPCClientImpl::UnregisterTraceWriter(uint32_t writer_id) {
67258   PERFETTO_DCHECK_THREAD(thread_checker_);
67259   if (!connected_) {
67260     PERFETTO_DLOG(
67261         "Cannot UnregisterTraceWriter(), not connected to tracing service");
67262     return;
67263   }
67264   protos::gen::UnregisterTraceWriterRequest req;
67265   req.set_trace_writer_id(writer_id);
67266   producer_port_.UnregisterTraceWriter(
67267       req, ipc::Deferred<protos::gen::UnregisterTraceWriterResponse>());
67268 }
67269 
CommitData(const CommitDataRequest & req,CommitDataCallback callback)67270 void ProducerIPCClientImpl::CommitData(const CommitDataRequest& req,
67271                                        CommitDataCallback callback) {
67272   PERFETTO_DCHECK_THREAD(thread_checker_);
67273   if (!connected_) {
67274     PERFETTO_DLOG("Cannot CommitData(), not connected to tracing service");
67275     return;
67276   }
67277   ipc::Deferred<protos::gen::CommitDataResponse> async_response;
67278   // TODO(primiano): add a test that destroys ProducerIPCClientImpl soon after
67279   // this call and checks that the callback is dropped.
67280   if (callback) {
67281     async_response.Bind(
67282         [callback](ipc::AsyncResult<protos::gen::CommitDataResponse> response) {
67283           if (!response) {
67284             PERFETTO_DLOG("CommitData() failed: connection reset");
67285             return;
67286           }
67287           callback();
67288         });
67289   }
67290   producer_port_.CommitData(req, std::move(async_response));
67291 }
67292 
NotifyDataSourceStarted(DataSourceInstanceID id)67293 void ProducerIPCClientImpl::NotifyDataSourceStarted(DataSourceInstanceID id) {
67294   PERFETTO_DCHECK_THREAD(thread_checker_);
67295   if (!connected_) {
67296     PERFETTO_DLOG(
67297         "Cannot NotifyDataSourceStarted(), not connected to tracing service");
67298     return;
67299   }
67300   protos::gen::NotifyDataSourceStartedRequest req;
67301   req.set_data_source_id(id);
67302   producer_port_.NotifyDataSourceStarted(
67303       req, ipc::Deferred<protos::gen::NotifyDataSourceStartedResponse>());
67304 }
67305 
NotifyDataSourceStopped(DataSourceInstanceID id)67306 void ProducerIPCClientImpl::NotifyDataSourceStopped(DataSourceInstanceID id) {
67307   PERFETTO_DCHECK_THREAD(thread_checker_);
67308   if (!connected_) {
67309     PERFETTO_DLOG(
67310         "Cannot NotifyDataSourceStopped(), not connected to tracing service");
67311     return;
67312   }
67313   protos::gen::NotifyDataSourceStoppedRequest req;
67314   req.set_data_source_id(id);
67315   producer_port_.NotifyDataSourceStopped(
67316       req, ipc::Deferred<protos::gen::NotifyDataSourceStoppedResponse>());
67317 }
67318 
ActivateTriggers(const std::vector<std::string> & triggers)67319 void ProducerIPCClientImpl::ActivateTriggers(
67320     const std::vector<std::string>& triggers) {
67321   PERFETTO_DCHECK_THREAD(thread_checker_);
67322   if (!connected_) {
67323     PERFETTO_DLOG(
67324         "Cannot ActivateTriggers(), not connected to tracing service");
67325     return;
67326   }
67327   protos::gen::ActivateTriggersRequest proto_req;
67328   for (const auto& name : triggers) {
67329     *proto_req.add_trigger_names() = name;
67330   }
67331   producer_port_.ActivateTriggers(
67332       proto_req, ipc::Deferred<protos::gen::ActivateTriggersResponse>());
67333 }
67334 
Sync(std::function<void ()> callback)67335 void ProducerIPCClientImpl::Sync(std::function<void()> callback) {
67336   PERFETTO_DCHECK_THREAD(thread_checker_);
67337   if (!connected_) {
67338     pending_sync_reqs_.emplace_back(std::move(callback));
67339     return;
67340   }
67341   ipc::Deferred<protos::gen::SyncResponse> resp;
67342   resp.Bind([callback](ipc::AsyncResult<protos::gen::SyncResponse>) {
67343     // Here we ACK the callback even if the service replies with a failure
67344     // (i.e. the service is too old and doesn't understand Sync()). In that
67345     // case the service has still seen the request, the IPC roundtrip is
67346     // still a (weaker) linearization fence.
67347     callback();
67348   });
67349   producer_port_.Sync(protos::gen::SyncRequest(), std::move(resp));
67350 }
67351 
CreateTraceWriter(BufferID target_buffer,BufferExhaustedPolicy buffer_exhausted_policy)67352 std::unique_ptr<TraceWriter> ProducerIPCClientImpl::CreateTraceWriter(
67353     BufferID target_buffer,
67354     BufferExhaustedPolicy buffer_exhausted_policy) {
67355   // This method can be called by different threads. |shared_memory_arbiter_| is
67356   // thread-safe but be aware of accessing any other state in this function.
67357   return shared_memory_arbiter_->CreateTraceWriter(target_buffer,
67358                                                    buffer_exhausted_policy);
67359 }
67360 
MaybeSharedMemoryArbiter()67361 SharedMemoryArbiter* ProducerIPCClientImpl::MaybeSharedMemoryArbiter() {
67362   return shared_memory_arbiter_.get();
67363 }
67364 
IsShmemProvidedByProducer() const67365 bool ProducerIPCClientImpl::IsShmemProvidedByProducer() const {
67366   return is_shmem_provided_by_producer_;
67367 }
67368 
NotifyFlushComplete(FlushRequestID req_id)67369 void ProducerIPCClientImpl::NotifyFlushComplete(FlushRequestID req_id) {
67370   return shared_memory_arbiter_->NotifyFlushComplete(req_id);
67371 }
67372 
shared_memory() const67373 SharedMemory* ProducerIPCClientImpl::shared_memory() const {
67374   return shared_memory_.get();
67375 }
67376 
shared_buffer_page_size_kb() const67377 size_t ProducerIPCClientImpl::shared_buffer_page_size_kb() const {
67378   return shared_buffer_page_size_kb_;
67379 }
67380 
67381 }  // namespace perfetto
67382 // gen_amalgamated begin source: src/tracing/ipc/service/consumer_ipc_service.cc
67383 // gen_amalgamated begin header: src/tracing/ipc/service/consumer_ipc_service.h
67384 /*
67385  * Copyright (C) 2017 The Android Open Source Project
67386  *
67387  * Licensed under the Apache License, Version 2.0 (the "License");
67388  * you may not use this file except in compliance with the License.
67389  * You may obtain a copy of the License at
67390  *
67391  *      http://www.apache.org/licenses/LICENSE-2.0
67392  *
67393  * Unless required by applicable law or agreed to in writing, software
67394  * distributed under the License is distributed on an "AS IS" BASIS,
67395  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
67396  * See the License for the specific language governing permissions and
67397  * limitations under the License.
67398  */
67399 
67400 #ifndef SRC_TRACING_IPC_SERVICE_CONSUMER_IPC_SERVICE_H_
67401 #define SRC_TRACING_IPC_SERVICE_CONSUMER_IPC_SERVICE_H_
67402 
67403 #include <list>
67404 #include <map>
67405 #include <memory>
67406 #include <string>
67407 
67408 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
67409 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
67410 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
67411 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
67412 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
67413 // gen_amalgamated expanded: #include "protos/perfetto/ipc/consumer_port.ipc.h"
67414 
67415 namespace perfetto {
67416 
67417 namespace ipc {
67418 class Host;
67419 }  // namespace ipc
67420 
67421 // Implements the Consumer port of the IPC service. This class proxies requests
67422 // and responses between the core service logic (|svc_|) and remote Consumer(s)
67423 // on the IPC socket, through the methods overriddden from ConsumerPort.
67424 class ConsumerIPCService : public protos::gen::ConsumerPort {
67425  public:
67426   explicit ConsumerIPCService(TracingService* core_service);
67427   ~ConsumerIPCService() override;
67428 
67429   // ConsumerPort implementation (from .proto IPC definition).
67430   void EnableTracing(const protos::gen::EnableTracingRequest&,
67431                      DeferredEnableTracingResponse) override;
67432   void StartTracing(const protos::gen::StartTracingRequest&,
67433                     DeferredStartTracingResponse) override;
67434   void ChangeTraceConfig(const protos::gen::ChangeTraceConfigRequest&,
67435                          DeferredChangeTraceConfigResponse) override;
67436   void DisableTracing(const protos::gen::DisableTracingRequest&,
67437                       DeferredDisableTracingResponse) override;
67438   void ReadBuffers(const protos::gen::ReadBuffersRequest&,
67439                    DeferredReadBuffersResponse) override;
67440   void FreeBuffers(const protos::gen::FreeBuffersRequest&,
67441                    DeferredFreeBuffersResponse) override;
67442   void Flush(const protos::gen::FlushRequest&, DeferredFlushResponse) override;
67443   void Detach(const protos::gen::DetachRequest&,
67444               DeferredDetachResponse) override;
67445   void Attach(const protos::gen::AttachRequest&,
67446               DeferredAttachResponse) override;
67447   void GetTraceStats(const protos::gen::GetTraceStatsRequest&,
67448                      DeferredGetTraceStatsResponse) override;
67449   void ObserveEvents(const protos::gen::ObserveEventsRequest&,
67450                      DeferredObserveEventsResponse) override;
67451   void QueryServiceState(const protos::gen::QueryServiceStateRequest&,
67452                          DeferredQueryServiceStateResponse) override;
67453   void QueryCapabilities(const protos::gen::QueryCapabilitiesRequest&,
67454                          DeferredQueryCapabilitiesResponse) override;
67455   void SaveTraceForBugreport(const protos::gen::SaveTraceForBugreportRequest&,
67456                              DeferredSaveTraceForBugreportResponse) override;
67457   void OnClientDisconnected() override;
67458 
67459  private:
67460   // Acts like a Consumer with the core Service business logic (which doesn't
67461   // know anything about the remote transport), but all it does is proxying
67462   // methods to the remote Consumer on the other side of the IPC channel.
67463   class RemoteConsumer : public Consumer {
67464    public:
67465     RemoteConsumer();
67466     ~RemoteConsumer() override;
67467 
67468     // These methods are called by the |core_service_| business logic. There is
67469     // no connection here, these methods are posted straight away.
67470     void OnConnect() override;
67471     void OnDisconnect() override;
67472     void OnTracingDisabled(const std::string& error) override;
67473     void OnTraceData(std::vector<TracePacket>, bool has_more) override;
67474     void OnDetach(bool) override;
67475     void OnAttach(bool, const TraceConfig&) override;
67476     void OnTraceStats(bool, const TraceStats&) override;
67477     void OnObservableEvents(const ObservableEvents&) override;
67478 
67479     void CloseObserveEventsResponseStream();
67480 
67481     // The interface obtained from the core service business logic through
67482     // TracingService::ConnectConsumer(this). This allows to invoke methods for
67483     // a specific Consumer on the Service business logic.
67484     std::unique_ptr<TracingService::ConsumerEndpoint> service_endpoint;
67485 
67486     // After ReadBuffers() is invoked, this binds the async callback that
67487     // allows to stream trace packets back to the client.
67488     DeferredReadBuffersResponse read_buffers_response;
67489 
67490     // After EnableTracing() is invoked, this binds the async callback that
67491     // allows to send the OnTracingDisabled notification.
67492     DeferredEnableTracingResponse enable_tracing_response;
67493 
67494     // After Detach() is invoked, this binds the async callback that allows to
67495     // send the session id to the consumer.
67496     DeferredDetachResponse detach_response;
67497 
67498     // As above, but for the Attach() case.
67499     DeferredAttachResponse attach_response;
67500 
67501     // As above, but for GetTraceStats().
67502     DeferredGetTraceStatsResponse get_trace_stats_response;
67503 
67504     // After ObserveEvents() is invoked, this binds the async callback that
67505     // allows to stream ObservableEvents back to the client.
67506     DeferredObserveEventsResponse observe_events_response;
67507   };
67508 
67509   // This has to be a container that doesn't invalidate iterators.
67510   using PendingFlushResponses = std::list<DeferredFlushResponse>;
67511   using PendingQuerySvcResponses = std::list<DeferredQueryServiceStateResponse>;
67512   using PendingQueryCapabilitiesResponses =
67513       std::list<DeferredQueryCapabilitiesResponse>;
67514   using PendingSaveTraceForBugreportResponses =
67515       std::list<DeferredSaveTraceForBugreportResponse>;
67516 
67517   ConsumerIPCService(const ConsumerIPCService&) = delete;
67518   ConsumerIPCService& operator=(const ConsumerIPCService&) = delete;
67519 
67520   // Returns the ConsumerEndpoint in the core business logic that corresponds to
67521   // the current IPC request.
67522   RemoteConsumer* GetConsumerForCurrentRequest();
67523 
67524   void OnFlushCallback(bool success, PendingFlushResponses::iterator);
67525   void OnQueryServiceCallback(bool success,
67526                               const TracingServiceState&,
67527                               PendingQuerySvcResponses::iterator);
67528   void OnQueryCapabilitiesCallback(const TracingServiceCapabilities&,
67529                                    PendingQueryCapabilitiesResponses::iterator);
67530   void OnSaveTraceForBugreportCallback(
67531       bool success,
67532       const std::string& msg,
67533       PendingSaveTraceForBugreportResponses::iterator);
67534 
67535   TracingService* const core_service_;
67536 
67537   // Maps IPC clients to ConsumerEndpoint instances registered on the
67538   // |core_service_| business logic.
67539   std::map<ipc::ClientID, std::unique_ptr<RemoteConsumer>> consumers_;
67540 
67541   PendingFlushResponses pending_flush_responses_;
67542   PendingQuerySvcResponses pending_query_service_responses_;
67543   PendingQueryCapabilitiesResponses pending_query_capabilities_responses_;
67544   PendingSaveTraceForBugreportResponses pending_bugreport_responses_;
67545 
67546   base::WeakPtrFactory<ConsumerIPCService> weak_ptr_factory_;  // Keep last.
67547 };
67548 
67549 }  // namespace perfetto
67550 
67551 #endif  // SRC_TRACING_IPC_SERVICE_CONSUMER_IPC_SERVICE_H_
67552 /*
67553  * Copyright (C) 2017 The Android Open Source Project
67554  *
67555  * Licensed under the Apache License, Version 2.0 (the "License");
67556  * you may not use this file except in compliance with the License.
67557  * You may obtain a copy of the License at
67558  *
67559  *      http://www.apache.org/licenses/LICENSE-2.0
67560  *
67561  * Unless required by applicable law or agreed to in writing, software
67562  * distributed under the License is distributed on an "AS IS" BASIS,
67563  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
67564  * See the License for the specific language governing permissions and
67565  * limitations under the License.
67566  */
67567 
67568 // gen_amalgamated expanded: #include "src/tracing/ipc/service/consumer_ipc_service.h"
67569 
67570 #include <inttypes.h>
67571 
67572 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
67573 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
67574 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
67575 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
67576 // gen_amalgamated expanded: #include "perfetto/ext/ipc/host.h"
67577 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
67578 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/slice.h"
67579 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
67580 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_stats.h"
67581 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
67582 // gen_amalgamated expanded: #include "perfetto/tracing/core/trace_config.h"
67583 // gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_capabilities.h"
67584 // gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_state.h"
67585 
67586 namespace perfetto {
67587 
ConsumerIPCService(TracingService * core_service)67588 ConsumerIPCService::ConsumerIPCService(TracingService* core_service)
67589     : core_service_(core_service), weak_ptr_factory_(this) {}
67590 
67591 ConsumerIPCService::~ConsumerIPCService() = default;
67592 
67593 ConsumerIPCService::RemoteConsumer*
GetConsumerForCurrentRequest()67594 ConsumerIPCService::GetConsumerForCurrentRequest() {
67595   const ipc::ClientID ipc_client_id = ipc::Service::client_info().client_id();
67596   const uid_t uid = ipc::Service::client_info().uid();
67597   PERFETTO_CHECK(ipc_client_id);
67598   auto it = consumers_.find(ipc_client_id);
67599   if (it == consumers_.end()) {
67600     auto* remote_consumer = new RemoteConsumer();
67601     consumers_[ipc_client_id].reset(remote_consumer);
67602     remote_consumer->service_endpoint =
67603         core_service_->ConnectConsumer(remote_consumer, uid);
67604     return remote_consumer;
67605   }
67606   return it->second.get();
67607 }
67608 
67609 // Called by the IPC layer.
OnClientDisconnected()67610 void ConsumerIPCService::OnClientDisconnected() {
67611   ipc::ClientID client_id = ipc::Service::client_info().client_id();
67612   consumers_.erase(client_id);
67613 }
67614 
67615 // Called by the IPC layer.
EnableTracing(const protos::gen::EnableTracingRequest & req,DeferredEnableTracingResponse resp)67616 void ConsumerIPCService::EnableTracing(
67617     const protos::gen::EnableTracingRequest& req,
67618     DeferredEnableTracingResponse resp) {
67619   RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
67620   if (req.attach_notification_only()) {
67621     remote_consumer->enable_tracing_response = std::move(resp);
67622     return;
67623   }
67624   const TraceConfig& trace_config = req.trace_config();
67625   base::ScopedFile fd;
67626   if (trace_config.write_into_file() && trace_config.output_path().empty())
67627     fd = ipc::Service::TakeReceivedFD();
67628   remote_consumer->service_endpoint->EnableTracing(trace_config, std::move(fd));
67629   remote_consumer->enable_tracing_response = std::move(resp);
67630 }
67631 
67632 // Called by the IPC layer.
StartTracing(const protos::gen::StartTracingRequest &,DeferredStartTracingResponse resp)67633 void ConsumerIPCService::StartTracing(const protos::gen::StartTracingRequest&,
67634                                       DeferredStartTracingResponse resp) {
67635   RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
67636   remote_consumer->service_endpoint->StartTracing();
67637   resp.Resolve(ipc::AsyncResult<protos::gen::StartTracingResponse>::Create());
67638 }
67639 
67640 // Called by the IPC layer.
ChangeTraceConfig(const protos::gen::ChangeTraceConfigRequest & req,DeferredChangeTraceConfigResponse resp)67641 void ConsumerIPCService::ChangeTraceConfig(
67642     const protos::gen::ChangeTraceConfigRequest& req,
67643     DeferredChangeTraceConfigResponse resp) {
67644   RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
67645   remote_consumer->service_endpoint->ChangeTraceConfig(req.trace_config());
67646   resp.Resolve(
67647       ipc::AsyncResult<protos::gen::ChangeTraceConfigResponse>::Create());
67648 }
67649 
67650 // Called by the IPC layer.
DisableTracing(const protos::gen::DisableTracingRequest &,DeferredDisableTracingResponse resp)67651 void ConsumerIPCService::DisableTracing(
67652     const protos::gen::DisableTracingRequest&,
67653     DeferredDisableTracingResponse resp) {
67654   GetConsumerForCurrentRequest()->service_endpoint->DisableTracing();
67655   resp.Resolve(ipc::AsyncResult<protos::gen::DisableTracingResponse>::Create());
67656 }
67657 
67658 // Called by the IPC layer.
ReadBuffers(const protos::gen::ReadBuffersRequest &,DeferredReadBuffersResponse resp)67659 void ConsumerIPCService::ReadBuffers(const protos::gen::ReadBuffersRequest&,
67660                                      DeferredReadBuffersResponse resp) {
67661   RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
67662   remote_consumer->read_buffers_response = std::move(resp);
67663   remote_consumer->service_endpoint->ReadBuffers();
67664 }
67665 
67666 // Called by the IPC layer.
FreeBuffers(const protos::gen::FreeBuffersRequest &,DeferredFreeBuffersResponse resp)67667 void ConsumerIPCService::FreeBuffers(const protos::gen::FreeBuffersRequest&,
67668                                      DeferredFreeBuffersResponse resp) {
67669   GetConsumerForCurrentRequest()->service_endpoint->FreeBuffers();
67670   resp.Resolve(ipc::AsyncResult<protos::gen::FreeBuffersResponse>::Create());
67671 }
67672 
67673 // Called by the IPC layer.
Flush(const protos::gen::FlushRequest & req,DeferredFlushResponse resp)67674 void ConsumerIPCService::Flush(const protos::gen::FlushRequest& req,
67675                                DeferredFlushResponse resp) {
67676   auto it = pending_flush_responses_.insert(pending_flush_responses_.end(),
67677                                             std::move(resp));
67678   auto weak_this = weak_ptr_factory_.GetWeakPtr();
67679   auto callback = [weak_this, it](bool success) {
67680     if (weak_this)
67681       weak_this->OnFlushCallback(success, std::move(it));
67682   };
67683   GetConsumerForCurrentRequest()->service_endpoint->Flush(req.timeout_ms(),
67684                                                           std::move(callback));
67685 }
67686 
67687 // Called by the IPC layer.
Detach(const protos::gen::DetachRequest & req,DeferredDetachResponse resp)67688 void ConsumerIPCService::Detach(const protos::gen::DetachRequest& req,
67689                                 DeferredDetachResponse resp) {
67690   // OnDetach() will resolve the |detach_response|.
67691   RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
67692   remote_consumer->detach_response = std::move(resp);
67693   remote_consumer->service_endpoint->Detach(req.key());
67694 }
67695 
67696 // Called by the IPC layer.
Attach(const protos::gen::AttachRequest & req,DeferredAttachResponse resp)67697 void ConsumerIPCService::Attach(const protos::gen::AttachRequest& req,
67698                                 DeferredAttachResponse resp) {
67699   // OnAttach() will resolve the |attach_response|.
67700   RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
67701   remote_consumer->attach_response = std::move(resp);
67702   remote_consumer->service_endpoint->Attach(req.key());
67703 }
67704 
67705 // Called by the IPC layer.
GetTraceStats(const protos::gen::GetTraceStatsRequest &,DeferredGetTraceStatsResponse resp)67706 void ConsumerIPCService::GetTraceStats(const protos::gen::GetTraceStatsRequest&,
67707                                        DeferredGetTraceStatsResponse resp) {
67708   // OnTraceStats() will resolve the |get_trace_stats_response|.
67709   RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
67710   remote_consumer->get_trace_stats_response = std::move(resp);
67711   remote_consumer->service_endpoint->GetTraceStats();
67712 }
67713 
67714 // Called by the IPC layer.
ObserveEvents(const protos::gen::ObserveEventsRequest & req,DeferredObserveEventsResponse resp)67715 void ConsumerIPCService::ObserveEvents(
67716     const protos::gen::ObserveEventsRequest& req,
67717     DeferredObserveEventsResponse resp) {
67718   RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
67719 
67720   // If there's a prior stream, close it so that client can clean it up.
67721   remote_consumer->CloseObserveEventsResponseStream();
67722 
67723   remote_consumer->observe_events_response = std::move(resp);
67724 
67725   uint32_t events_mask = 0;
67726   for (const auto& type : req.events_to_observe()) {
67727     events_mask |= static_cast<uint32_t>(type);
67728   }
67729   remote_consumer->service_endpoint->ObserveEvents(events_mask);
67730 
67731   // If no events are to be observed, close the stream immediately so that the
67732   // client can clean up.
67733   if (events_mask == 0)
67734     remote_consumer->CloseObserveEventsResponseStream();
67735 }
67736 
67737 // Called by the IPC layer.
QueryServiceState(const protos::gen::QueryServiceStateRequest &,DeferredQueryServiceStateResponse resp)67738 void ConsumerIPCService::QueryServiceState(
67739     const protos::gen::QueryServiceStateRequest&,
67740     DeferredQueryServiceStateResponse resp) {
67741   RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
67742   auto it = pending_query_service_responses_.insert(
67743       pending_query_service_responses_.end(), std::move(resp));
67744   auto weak_this = weak_ptr_factory_.GetWeakPtr();
67745   auto callback = [weak_this, it](bool success,
67746                                   const TracingServiceState& svc_state) {
67747     if (weak_this)
67748       weak_this->OnQueryServiceCallback(success, svc_state, std::move(it));
67749   };
67750   remote_consumer->service_endpoint->QueryServiceState(callback);
67751 }
67752 
67753 // Called by the service in response to service_endpoint->QueryServiceState().
OnQueryServiceCallback(bool success,const TracingServiceState & svc_state,PendingQuerySvcResponses::iterator pending_response_it)67754 void ConsumerIPCService::OnQueryServiceCallback(
67755     bool success,
67756     const TracingServiceState& svc_state,
67757     PendingQuerySvcResponses::iterator pending_response_it) {
67758   DeferredQueryServiceStateResponse response(std::move(*pending_response_it));
67759   pending_query_service_responses_.erase(pending_response_it);
67760   if (!success) {
67761     response.Reject();
67762     return;
67763   }
67764 
67765   // The TracingServiceState object might be too big to fit into a single IPC
67766   // message because it contains the DataSourceDescriptor of each data source.
67767   // Here we split it in chunks to fit in the IPC limit, observing the
67768   // following rule: each chunk must be invididually a valid TracingServiceState
67769   // message; all the chunks concatenated together must form the original
67770   // message. This is to deal with the legacy API that was just sending one
67771   // whole message (failing in presence of too many data sources, b/153142114).
67772   // The message is split as follows: we take the whole TracingServiceState,
67773   // take out the data sources section (which is a top-level repeated field)
67774   // and re-add them one-by-one. If, in the process of appending, the IPC msg
67775   // size is reached, a new chunk is created. This assumes that the rest of
67776   // TracingServiceState fits in one IPC message and each DataSourceDescriptor
67777   // fits in the worst case in a dedicated message (which is true, because
67778   // otherwise the RegisterDataSource() which passes the descriptor in the first
67779   // place would fail).
67780 
67781   std::vector<uint8_t> chunked_reply;
67782 
67783   // Transmits the current chunk and starts a new one.
67784   bool sent_eof = false;
67785   auto send_chunked_reply = [&chunked_reply, &response,
67786                              &sent_eof](bool has_more) {
67787     PERFETTO_CHECK(!sent_eof);
67788     sent_eof = !has_more;
67789     auto resp =
67790         ipc::AsyncResult<protos::gen::QueryServiceStateResponse>::Create();
67791     resp.set_has_more(has_more);
67792     PERFETTO_CHECK(resp->mutable_service_state()->ParseFromArray(
67793         chunked_reply.data(), chunked_reply.size()));
67794     chunked_reply.clear();
67795     response.Resolve(std::move(resp));
67796   };
67797 
67798   // Create a copy of the whole response and cut away the data_sources section.
67799   protos::gen::TracingServiceState svc_state_copy = svc_state;
67800   auto data_sources = std::move(*svc_state_copy.mutable_data_sources());
67801   chunked_reply = svc_state_copy.SerializeAsArray();
67802 
67803   // Now re-add them fitting within the IPC message limits (- some margin for
67804   // the outer IPC frame).
67805   constexpr size_t kMaxMsgSize = ipc::kIPCBufferSize - 128;
67806   for (const auto& data_source : data_sources) {
67807     protos::gen::TracingServiceState tmp;
67808     tmp.mutable_data_sources()->emplace_back(std::move(data_source));
67809     std::vector<uint8_t> chunk = tmp.SerializeAsArray();
67810     if (chunked_reply.size() + chunk.size() < kMaxMsgSize) {
67811       chunked_reply.insert(chunked_reply.end(), chunk.begin(), chunk.end());
67812     } else {
67813       send_chunked_reply(/*has_more=*/true);
67814       chunked_reply = std::move(chunk);
67815     }
67816   }
67817 
67818   PERFETTO_DCHECK(!chunked_reply.empty());
67819   send_chunked_reply(/*has_more=*/false);
67820   PERFETTO_CHECK(sent_eof);
67821 }
67822 
67823 // Called by the service in response to a service_endpoint->Flush() request.
OnFlushCallback(bool success,PendingFlushResponses::iterator pending_response_it)67824 void ConsumerIPCService::OnFlushCallback(
67825     bool success,
67826     PendingFlushResponses::iterator pending_response_it) {
67827   DeferredFlushResponse response(std::move(*pending_response_it));
67828   pending_flush_responses_.erase(pending_response_it);
67829   if (success) {
67830     response.Resolve(ipc::AsyncResult<protos::gen::FlushResponse>::Create());
67831   } else {
67832     response.Reject();
67833   }
67834 }
67835 
QueryCapabilities(const protos::gen::QueryCapabilitiesRequest &,DeferredQueryCapabilitiesResponse resp)67836 void ConsumerIPCService::QueryCapabilities(
67837     const protos::gen::QueryCapabilitiesRequest&,
67838     DeferredQueryCapabilitiesResponse resp) {
67839   RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
67840   auto it = pending_query_capabilities_responses_.insert(
67841       pending_query_capabilities_responses_.end(), std::move(resp));
67842   auto weak_this = weak_ptr_factory_.GetWeakPtr();
67843   auto callback = [weak_this, it](const TracingServiceCapabilities& caps) {
67844     if (weak_this)
67845       weak_this->OnQueryCapabilitiesCallback(caps, std::move(it));
67846   };
67847   remote_consumer->service_endpoint->QueryCapabilities(callback);
67848 }
67849 
67850 // Called by the service in response to service_endpoint->QueryCapabilities().
OnQueryCapabilitiesCallback(const TracingServiceCapabilities & caps,PendingQueryCapabilitiesResponses::iterator pending_response_it)67851 void ConsumerIPCService::OnQueryCapabilitiesCallback(
67852     const TracingServiceCapabilities& caps,
67853     PendingQueryCapabilitiesResponses::iterator pending_response_it) {
67854   DeferredQueryCapabilitiesResponse response(std::move(*pending_response_it));
67855   pending_query_capabilities_responses_.erase(pending_response_it);
67856   auto resp =
67857       ipc::AsyncResult<protos::gen::QueryCapabilitiesResponse>::Create();
67858   *resp->mutable_capabilities() = caps;
67859   response.Resolve(std::move(resp));
67860 }
67861 
SaveTraceForBugreport(const protos::gen::SaveTraceForBugreportRequest &,DeferredSaveTraceForBugreportResponse resp)67862 void ConsumerIPCService::SaveTraceForBugreport(
67863     const protos::gen::SaveTraceForBugreportRequest&,
67864     DeferredSaveTraceForBugreportResponse resp) {
67865   RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
67866   auto it = pending_bugreport_responses_.insert(
67867       pending_bugreport_responses_.end(), std::move(resp));
67868   auto weak_this = weak_ptr_factory_.GetWeakPtr();
67869   auto callback = [weak_this, it](bool success, const std::string& msg) {
67870     if (weak_this)
67871       weak_this->OnSaveTraceForBugreportCallback(success, msg, std::move(it));
67872   };
67873   remote_consumer->service_endpoint->SaveTraceForBugreport(callback);
67874 }
67875 
67876 // Called by the service in response to
67877 // service_endpoint->SaveTraceForBugreport().
OnSaveTraceForBugreportCallback(bool success,const std::string & msg,PendingSaveTraceForBugreportResponses::iterator pending_response_it)67878 void ConsumerIPCService::OnSaveTraceForBugreportCallback(
67879     bool success,
67880     const std::string& msg,
67881     PendingSaveTraceForBugreportResponses::iterator pending_response_it) {
67882   DeferredSaveTraceForBugreportResponse response(
67883       std::move(*pending_response_it));
67884   pending_bugreport_responses_.erase(pending_response_it);
67885   auto resp =
67886       ipc::AsyncResult<protos::gen::SaveTraceForBugreportResponse>::Create();
67887   resp->set_success(success);
67888   resp->set_msg(msg);
67889   response.Resolve(std::move(resp));
67890 }
67891 
67892 ////////////////////////////////////////////////////////////////////////////////
67893 // RemoteConsumer methods
67894 ////////////////////////////////////////////////////////////////////////////////
67895 
67896 ConsumerIPCService::RemoteConsumer::RemoteConsumer() = default;
67897 ConsumerIPCService::RemoteConsumer::~RemoteConsumer() = default;
67898 
67899 // Invoked by the |core_service_| business logic after the ConnectConsumer()
67900 // call. There is nothing to do here, we really expected the ConnectConsumer()
67901 // to just work in the local case.
OnConnect()67902 void ConsumerIPCService::RemoteConsumer::OnConnect() {}
67903 
67904 // Invoked by the |core_service_| business logic after we destroy the
67905 // |service_endpoint| (in the RemoteConsumer dtor).
OnDisconnect()67906 void ConsumerIPCService::RemoteConsumer::OnDisconnect() {}
67907 
OnTracingDisabled(const std::string & error)67908 void ConsumerIPCService::RemoteConsumer::OnTracingDisabled(
67909     const std::string& error) {
67910   if (enable_tracing_response.IsBound()) {
67911     auto result =
67912         ipc::AsyncResult<protos::gen::EnableTracingResponse>::Create();
67913     result->set_disabled(true);
67914     if (!error.empty())
67915       result->set_error(error);
67916     enable_tracing_response.Resolve(std::move(result));
67917   }
67918 }
67919 
OnTraceData(std::vector<TracePacket> trace_packets,bool has_more)67920 void ConsumerIPCService::RemoteConsumer::OnTraceData(
67921     std::vector<TracePacket> trace_packets,
67922     bool has_more) {
67923   if (!read_buffers_response.IsBound())
67924     return;
67925 
67926   auto result = ipc::AsyncResult<protos::gen::ReadBuffersResponse>::Create();
67927 
67928   // A TracePacket might be too big to fit into a single IPC message (max
67929   // kIPCBufferSize). However a TracePacket is made of slices and each slice
67930   // is way smaller than kIPCBufferSize (a slice size is effectively bounded by
67931   // the max chunk size of the SharedMemoryABI). When sending a TracePacket,
67932   // if its slices don't fit within one IPC, chunk them over several contiguous
67933   // IPCs using the |last_slice_for_packet| for glueing on the other side.
67934   static_assert(ipc::kIPCBufferSize >= SharedMemoryABI::kMaxPageSize * 2,
67935                 "kIPCBufferSize too small given the max possible slice size");
67936 
67937   auto send_ipc_reply = [this, &result](bool more) {
67938     result.set_has_more(more);
67939     read_buffers_response.Resolve(std::move(result));
67940     result = ipc::AsyncResult<protos::gen::ReadBuffersResponse>::Create();
67941   };
67942 
67943   size_t approx_reply_size = 0;
67944   for (const TracePacket& trace_packet : trace_packets) {
67945     size_t num_slices_left_for_packet = trace_packet.slices().size();
67946     for (const Slice& slice : trace_packet.slices()) {
67947       // Check if this slice would cause the IPC to overflow its max size and,
67948       // if that is the case, split the IPCs. The "16" and "64" below are
67949       // over-estimations of, respectively:
67950       // 16: the preamble that prefixes each slice (there are 2 x size fields
67951       //     in the proto + the |last_slice_for_packet| bool).
67952       // 64: the overhead of the IPC InvokeMethodReply + wire_protocol's frame.
67953       // If these estimations are wrong, BufferedFrameDeserializer::Serialize()
67954       // will hit a DCHECK anyways.
67955       const size_t approx_slice_size = slice.size + 16;
67956       if (approx_reply_size + approx_slice_size > ipc::kIPCBufferSize - 64) {
67957         // If we hit this CHECK we got a single slice that is > kIPCBufferSize.
67958         PERFETTO_CHECK(result->slices_size() > 0);
67959         send_ipc_reply(/*has_more=*/true);
67960         approx_reply_size = 0;
67961       }
67962       approx_reply_size += approx_slice_size;
67963 
67964       auto* res_slice = result->add_slices();
67965       res_slice->set_last_slice_for_packet(--num_slices_left_for_packet == 0);
67966       res_slice->set_data(slice.start, slice.size);
67967     }
67968   }
67969   send_ipc_reply(has_more);
67970 }
67971 
OnDetach(bool success)67972 void ConsumerIPCService::RemoteConsumer::OnDetach(bool success) {
67973   if (!success) {
67974     std::move(detach_response).Reject();
67975     return;
67976   }
67977   auto resp = ipc::AsyncResult<protos::gen::DetachResponse>::Create();
67978   std::move(detach_response).Resolve(std::move(resp));
67979 }
67980 
OnAttach(bool success,const TraceConfig & trace_config)67981 void ConsumerIPCService::RemoteConsumer::OnAttach(
67982     bool success,
67983     const TraceConfig& trace_config) {
67984   if (!success) {
67985     std::move(attach_response).Reject();
67986     return;
67987   }
67988   auto response = ipc::AsyncResult<protos::gen::AttachResponse>::Create();
67989   *response->mutable_trace_config() = trace_config;
67990   std::move(attach_response).Resolve(std::move(response));
67991 }
67992 
OnTraceStats(bool success,const TraceStats & stats)67993 void ConsumerIPCService::RemoteConsumer::OnTraceStats(bool success,
67994                                                       const TraceStats& stats) {
67995   if (!success) {
67996     std::move(get_trace_stats_response).Reject();
67997     return;
67998   }
67999   auto response =
68000       ipc::AsyncResult<protos::gen::GetTraceStatsResponse>::Create();
68001   *response->mutable_trace_stats() = stats;
68002   std::move(get_trace_stats_response).Resolve(std::move(response));
68003 }
68004 
OnObservableEvents(const ObservableEvents & events)68005 void ConsumerIPCService::RemoteConsumer::OnObservableEvents(
68006     const ObservableEvents& events) {
68007   if (!observe_events_response.IsBound())
68008     return;
68009 
68010   auto result = ipc::AsyncResult<protos::gen::ObserveEventsResponse>::Create();
68011   result.set_has_more(true);
68012   *result->mutable_events() = events;
68013   observe_events_response.Resolve(std::move(result));
68014 }
68015 
CloseObserveEventsResponseStream()68016 void ConsumerIPCService::RemoteConsumer::CloseObserveEventsResponseStream() {
68017   if (!observe_events_response.IsBound())
68018     return;
68019 
68020   auto result = ipc::AsyncResult<protos::gen::ObserveEventsResponse>::Create();
68021   result.set_has_more(false);
68022   observe_events_response.Resolve(std::move(result));
68023 }
68024 
68025 }  // namespace perfetto
68026 // gen_amalgamated begin source: src/tracing/ipc/service/producer_ipc_service.cc
68027 // gen_amalgamated begin header: src/tracing/ipc/service/producer_ipc_service.h
68028 /*
68029  * Copyright (C) 2017 The Android Open Source Project
68030  *
68031  * Licensed under the Apache License, Version 2.0 (the "License");
68032  * you may not use this file except in compliance with the License.
68033  * You may obtain a copy of the License at
68034  *
68035  *      http://www.apache.org/licenses/LICENSE-2.0
68036  *
68037  * Unless required by applicable law or agreed to in writing, software
68038  * distributed under the License is distributed on an "AS IS" BASIS,
68039  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68040  * See the License for the specific language governing permissions and
68041  * limitations under the License.
68042  */
68043 
68044 #ifndef SRC_TRACING_IPC_SERVICE_PRODUCER_IPC_SERVICE_H_
68045 #define SRC_TRACING_IPC_SERVICE_PRODUCER_IPC_SERVICE_H_
68046 
68047 #include <list>
68048 #include <map>
68049 #include <memory>
68050 #include <string>
68051 
68052 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
68053 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
68054 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
68055 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
68056 
68057 // gen_amalgamated expanded: #include "protos/perfetto/ipc/producer_port.ipc.h"
68058 
68059 namespace perfetto {
68060 
68061 namespace ipc {
68062 class Host;
68063 }  // namespace ipc
68064 
68065 // Implements the Producer port of the IPC service. This class proxies requests
68066 // and responses between the core service logic (|svc_|) and remote Producer(s)
68067 // on the IPC socket, through the methods overriddden from ProducerPort.
68068 class ProducerIPCService : public protos::gen::ProducerPort {
68069  public:
68070   explicit ProducerIPCService(TracingService* core_service);
68071   ~ProducerIPCService() override;
68072 
68073   // ProducerPort implementation (from .proto IPC definition).
68074   void InitializeConnection(const protos::gen::InitializeConnectionRequest&,
68075                             DeferredInitializeConnectionResponse) override;
68076   void RegisterDataSource(const protos::gen::RegisterDataSourceRequest&,
68077                           DeferredRegisterDataSourceResponse) override;
68078   void UnregisterDataSource(const protos::gen::UnregisterDataSourceRequest&,
68079                             DeferredUnregisterDataSourceResponse) override;
68080   void RegisterTraceWriter(const protos::gen::RegisterTraceWriterRequest&,
68081                            DeferredRegisterTraceWriterResponse) override;
68082   void UnregisterTraceWriter(const protos::gen::UnregisterTraceWriterRequest&,
68083                              DeferredUnregisterTraceWriterResponse) override;
68084   void CommitData(const protos::gen::CommitDataRequest&,
68085                   DeferredCommitDataResponse) override;
68086   void NotifyDataSourceStarted(
68087       const protos::gen::NotifyDataSourceStartedRequest&,
68088       DeferredNotifyDataSourceStartedResponse) override;
68089   void NotifyDataSourceStopped(
68090       const protos::gen::NotifyDataSourceStoppedRequest&,
68091       DeferredNotifyDataSourceStoppedResponse) override;
68092   void ActivateTriggers(const protos::gen::ActivateTriggersRequest&,
68093                         DeferredActivateTriggersResponse) override;
68094 
68095   void GetAsyncCommand(const protos::gen::GetAsyncCommandRequest&,
68096                        DeferredGetAsyncCommandResponse) override;
68097   void Sync(const protos::gen::SyncRequest&, DeferredSyncResponse) override;
68098   void OnClientDisconnected() override;
68099 
68100  private:
68101   // Acts like a Producer with the core Service business logic (which doesn't
68102   // know anything about the remote transport), but all it does is proxying
68103   // methods to the remote Producer on the other side of the IPC channel.
68104   class RemoteProducer : public Producer {
68105    public:
68106     RemoteProducer();
68107     ~RemoteProducer() override;
68108 
68109     // These methods are called by the |core_service_| business logic. There is
68110     // no connection here, these methods are posted straight away.
68111     void OnConnect() override;
68112     void OnDisconnect() override;
68113     void SetupDataSource(DataSourceInstanceID,
68114                          const DataSourceConfig&) override;
68115     void StartDataSource(DataSourceInstanceID,
68116                          const DataSourceConfig&) override;
68117     void StopDataSource(DataSourceInstanceID) override;
68118     void OnTracingSetup() override;
68119     void Flush(FlushRequestID,
68120                const DataSourceInstanceID* data_source_ids,
68121                size_t num_data_sources) override;
68122 
68123     void ClearIncrementalState(const DataSourceInstanceID* data_source_ids,
68124                                size_t num_data_sources) override;
68125 
68126     void SendSetupTracing();
68127 
68128     // The interface obtained from the core service business logic through
68129     // Service::ConnectProducer(this). This allows to invoke methods for a
68130     // specific Producer on the Service business logic.
68131     std::unique_ptr<TracingService::ProducerEndpoint> service_endpoint;
68132 
68133     // The back-channel (based on a never ending stream request) that allows us
68134     // to send asynchronous commands to the remote Producer (e.g. start/stop a
68135     // data source).
68136     DeferredGetAsyncCommandResponse async_producer_commands;
68137 
68138     // Set if the service calls OnTracingSetup() before the
68139     // |async_producer_commands| was bound by the service. In this case, we
68140     // forward the SetupTracing command when it is bound later.
68141     bool send_setup_tracing_on_async_commands_bound = false;
68142   };
68143 
68144   ProducerIPCService(const ProducerIPCService&) = delete;
68145   ProducerIPCService& operator=(const ProducerIPCService&) = delete;
68146 
68147   // Returns the ProducerEndpoint in the core business logic that corresponds to
68148   // the current IPC request.
68149   RemoteProducer* GetProducerForCurrentRequest();
68150 
68151   TracingService* const core_service_;
68152 
68153   // Maps IPC clients to ProducerEndpoint instances registered on the
68154   // |core_service_| business logic.
68155   std::map<ipc::ClientID, std::unique_ptr<RemoteProducer>> producers_;
68156 
68157   // List because pointers need to be stable.
68158   std::list<DeferredSyncResponse> pending_syncs_;
68159 
68160   base::WeakPtrFactory<ProducerIPCService> weak_ptr_factory_;  // Keep last.
68161 };
68162 
68163 }  // namespace perfetto
68164 
68165 #endif  // SRC_TRACING_IPC_SERVICE_PRODUCER_IPC_SERVICE_H_
68166 /*
68167  * Copyright (C) 2017 The Android Open Source Project
68168  *
68169  * Licensed under the Apache License, Version 2.0 (the "License");
68170  * you may not use this file except in compliance with the License.
68171  * You may obtain a copy of the License at
68172  *
68173  *      http://www.apache.org/licenses/LICENSE-2.0
68174  *
68175  * Unless required by applicable law or agreed to in writing, software
68176  * distributed under the License is distributed on an "AS IS" BASIS,
68177  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68178  * See the License for the specific language governing permissions and
68179  * limitations under the License.
68180  */
68181 
68182 // gen_amalgamated expanded: #include "src/tracing/ipc/service/producer_ipc_service.h"
68183 
68184 #include <inttypes.h>
68185 
68186 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
68187 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
68188 // gen_amalgamated expanded: #include "perfetto/ext/ipc/host.h"
68189 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
68190 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/commit_data_request.h"
68191 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
68192 // gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
68193 // gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
68194 // gen_amalgamated expanded: #include "src/tracing/ipc/posix_shared_memory.h"
68195 
68196 // The remote Producer(s) are not trusted. All the methods from the ProducerPort
68197 // IPC layer (e.g. RegisterDataSource()) must assume that the remote Producer is
68198 // compromised.
68199 
68200 namespace perfetto {
68201 
ProducerIPCService(TracingService * core_service)68202 ProducerIPCService::ProducerIPCService(TracingService* core_service)
68203     : core_service_(core_service), weak_ptr_factory_(this) {}
68204 
68205 ProducerIPCService::~ProducerIPCService() = default;
68206 
68207 ProducerIPCService::RemoteProducer*
GetProducerForCurrentRequest()68208 ProducerIPCService::GetProducerForCurrentRequest() {
68209   const ipc::ClientID ipc_client_id = ipc::Service::client_info().client_id();
68210   PERFETTO_CHECK(ipc_client_id);
68211   auto it = producers_.find(ipc_client_id);
68212   if (it == producers_.end())
68213     return nullptr;
68214   return it->second.get();
68215 }
68216 
68217 // Called by the remote Producer through the IPC channel soon after connecting.
InitializeConnection(const protos::gen::InitializeConnectionRequest & req,DeferredInitializeConnectionResponse response)68218 void ProducerIPCService::InitializeConnection(
68219     const protos::gen::InitializeConnectionRequest& req,
68220     DeferredInitializeConnectionResponse response) {
68221   const auto& client_info = ipc::Service::client_info();
68222   const ipc::ClientID ipc_client_id = client_info.client_id();
68223   PERFETTO_CHECK(ipc_client_id);
68224 
68225   if (producers_.count(ipc_client_id) > 0) {
68226     PERFETTO_DLOG(
68227         "The remote Producer is trying to re-initialize the connection");
68228     return response.Reject();
68229   }
68230 
68231   // Create a new entry.
68232   std::unique_ptr<RemoteProducer> producer(new RemoteProducer());
68233 
68234   TracingService::ProducerSMBScrapingMode smb_scraping_mode =
68235       TracingService::ProducerSMBScrapingMode::kDefault;
68236   switch (req.smb_scraping_mode()) {
68237     case protos::gen::InitializeConnectionRequest::SMB_SCRAPING_UNSPECIFIED:
68238       break;
68239     case protos::gen::InitializeConnectionRequest::SMB_SCRAPING_DISABLED:
68240       smb_scraping_mode = TracingService::ProducerSMBScrapingMode::kDisabled;
68241       break;
68242     case protos::gen::InitializeConnectionRequest::SMB_SCRAPING_ENABLED:
68243       smb_scraping_mode = TracingService::ProducerSMBScrapingMode::kEnabled;
68244       break;
68245   }
68246 
68247 #if PERFETTO_DCHECK_IS_ON()
68248   if (req.build_flags() ==
68249       protos::gen::InitializeConnectionRequest::BUILD_FLAGS_DCHECKS_OFF) {
68250     PERFETTO_LOG(
68251         "The producer is built with NDEBUG but the service binary was built "
68252         "with the DEBUG flag. This will likely cause crashes.");
68253     // The other way round (DEBUG producer with NDEBUG service) is expected to
68254     // work.
68255   }
68256 #endif
68257 
68258   // If the producer provided an SMB, tell the service to attempt to adopt it.
68259   std::unique_ptr<SharedMemory> shmem;
68260   if (req.producer_provided_shmem()) {
68261     base::ScopedFile shmem_fd = ipc::Service::TakeReceivedFD();
68262     if (shmem_fd) {
68263       shmem = PosixSharedMemory::AttachToFd(
68264           std::move(shmem_fd), /*require_seals_if_supported=*/true);
68265       if (!shmem) {
68266         PERFETTO_ELOG(
68267             "Couldn't map producer-provided SMB, falling back to "
68268             "service-provided SMB");
68269       }
68270     } else {
68271       PERFETTO_DLOG(
68272           "InitializeConnectionRequest's producer_provided_shmem flag is set "
68273           "but the producer didn't provide an FD");
68274     }
68275   }
68276 
68277   // ConnectProducer will call OnConnect() on the next task.
68278   producer->service_endpoint = core_service_->ConnectProducer(
68279       producer.get(), client_info.uid(), req.producer_name(),
68280       req.shared_memory_size_hint_bytes(),
68281       /*in_process=*/false, smb_scraping_mode,
68282       req.shared_memory_page_size_hint_bytes(), std::move(shmem),
68283       req.sdk_version());
68284 
68285   // Could happen if the service has too many producers connected.
68286   if (!producer->service_endpoint) {
68287     response.Reject();
68288     return;
68289   }
68290 
68291   bool using_producer_shmem =
68292       producer->service_endpoint->IsShmemProvidedByProducer();
68293 
68294   producers_.emplace(ipc_client_id, std::move(producer));
68295   // Because of the std::move() |producer| is invalid after this point.
68296 
68297   auto async_res =
68298       ipc::AsyncResult<protos::gen::InitializeConnectionResponse>::Create();
68299   async_res->set_using_shmem_provided_by_producer(using_producer_shmem);
68300   async_res->set_direct_smb_patching_supported(true);
68301   response.Resolve(std::move(async_res));
68302 }
68303 
68304 // Called by the remote Producer through the IPC channel.
RegisterDataSource(const protos::gen::RegisterDataSourceRequest & req,DeferredRegisterDataSourceResponse response)68305 void ProducerIPCService::RegisterDataSource(
68306     const protos::gen::RegisterDataSourceRequest& req,
68307     DeferredRegisterDataSourceResponse response) {
68308   RemoteProducer* producer = GetProducerForCurrentRequest();
68309   if (!producer) {
68310     PERFETTO_DLOG(
68311         "Producer invoked RegisterDataSource() before InitializeConnection()");
68312     if (response.IsBound())
68313       response.Reject();
68314     return;
68315   }
68316 
68317   const DataSourceDescriptor& dsd = req.data_source_descriptor();
68318   GetProducerForCurrentRequest()->service_endpoint->RegisterDataSource(dsd);
68319 
68320   // RegisterDataSource doesn't expect any meaningful response.
68321   if (response.IsBound()) {
68322     response.Resolve(
68323         ipc::AsyncResult<protos::gen::RegisterDataSourceResponse>::Create());
68324   }
68325 }
68326 
68327 // Called by the IPC layer.
OnClientDisconnected()68328 void ProducerIPCService::OnClientDisconnected() {
68329   ipc::ClientID client_id = ipc::Service::client_info().client_id();
68330   PERFETTO_DLOG("Client %" PRIu64 " disconnected", client_id);
68331   producers_.erase(client_id);
68332 }
68333 
68334 // TODO(fmayer): test what happens if we receive the following tasks, in order:
68335 // RegisterDataSource, UnregisterDataSource, OnDataSourceRegistered.
68336 // which essentially means that the client posted back to back a
68337 // ReqisterDataSource and UnregisterDataSource speculating on the next id.
68338 // Called by the remote Service through the IPC channel.
UnregisterDataSource(const protos::gen::UnregisterDataSourceRequest & req,DeferredUnregisterDataSourceResponse response)68339 void ProducerIPCService::UnregisterDataSource(
68340     const protos::gen::UnregisterDataSourceRequest& req,
68341     DeferredUnregisterDataSourceResponse response) {
68342   RemoteProducer* producer = GetProducerForCurrentRequest();
68343   if (!producer) {
68344     PERFETTO_DLOG(
68345         "Producer invoked UnregisterDataSource() before "
68346         "InitializeConnection()");
68347     if (response.IsBound())
68348       response.Reject();
68349     return;
68350   }
68351   producer->service_endpoint->UnregisterDataSource(req.data_source_name());
68352 
68353   // UnregisterDataSource doesn't expect any meaningful response.
68354   if (response.IsBound()) {
68355     response.Resolve(
68356         ipc::AsyncResult<protos::gen::UnregisterDataSourceResponse>::Create());
68357   }
68358 }
68359 
RegisterTraceWriter(const protos::gen::RegisterTraceWriterRequest & req,DeferredRegisterTraceWriterResponse response)68360 void ProducerIPCService::RegisterTraceWriter(
68361     const protos::gen::RegisterTraceWriterRequest& req,
68362     DeferredRegisterTraceWriterResponse response) {
68363   RemoteProducer* producer = GetProducerForCurrentRequest();
68364   if (!producer) {
68365     PERFETTO_DLOG(
68366         "Producer invoked RegisterTraceWriter() before "
68367         "InitializeConnection()");
68368     if (response.IsBound())
68369       response.Reject();
68370     return;
68371   }
68372   producer->service_endpoint->RegisterTraceWriter(req.trace_writer_id(),
68373                                                   req.target_buffer());
68374 
68375   // RegisterTraceWriter doesn't expect any meaningful response.
68376   if (response.IsBound()) {
68377     response.Resolve(
68378         ipc::AsyncResult<protos::gen::RegisterTraceWriterResponse>::Create());
68379   }
68380 }
68381 
UnregisterTraceWriter(const protos::gen::UnregisterTraceWriterRequest & req,DeferredUnregisterTraceWriterResponse response)68382 void ProducerIPCService::UnregisterTraceWriter(
68383     const protos::gen::UnregisterTraceWriterRequest& req,
68384     DeferredUnregisterTraceWriterResponse response) {
68385   RemoteProducer* producer = GetProducerForCurrentRequest();
68386   if (!producer) {
68387     PERFETTO_DLOG(
68388         "Producer invoked UnregisterTraceWriter() before "
68389         "InitializeConnection()");
68390     if (response.IsBound())
68391       response.Reject();
68392     return;
68393   }
68394   producer->service_endpoint->UnregisterTraceWriter(req.trace_writer_id());
68395 
68396   // UnregisterTraceWriter doesn't expect any meaningful response.
68397   if (response.IsBound()) {
68398     response.Resolve(
68399         ipc::AsyncResult<protos::gen::UnregisterTraceWriterResponse>::Create());
68400   }
68401 }
68402 
CommitData(const protos::gen::CommitDataRequest & req,DeferredCommitDataResponse resp)68403 void ProducerIPCService::CommitData(const protos::gen::CommitDataRequest& req,
68404                                     DeferredCommitDataResponse resp) {
68405   RemoteProducer* producer = GetProducerForCurrentRequest();
68406   if (!producer) {
68407     PERFETTO_DLOG(
68408         "Producer invoked CommitData() before InitializeConnection()");
68409     if (resp.IsBound())
68410       resp.Reject();
68411     return;
68412   }
68413 
68414   // We don't want to send a response if the client didn't attach a callback to
68415   // the original request. Doing so would generate unnecessary wakeups and
68416   // context switches.
68417   std::function<void()> callback;
68418   if (resp.IsBound()) {
68419     // Capturing |resp| by reference here speculates on the fact that
68420     // CommitData() in tracing_service_impl.cc invokes the passed callback
68421     // inline, without posting it. If that assumption changes this code needs to
68422     // wrap the response in a shared_ptr (C+11 lambdas don't support move) and
68423     // use a weak ptr in the caller.
68424     callback = [&resp] {
68425       resp.Resolve(ipc::AsyncResult<protos::gen::CommitDataResponse>::Create());
68426     };
68427   }
68428   producer->service_endpoint->CommitData(req, callback);
68429 }
68430 
NotifyDataSourceStarted(const protos::gen::NotifyDataSourceStartedRequest & request,DeferredNotifyDataSourceStartedResponse response)68431 void ProducerIPCService::NotifyDataSourceStarted(
68432     const protos::gen::NotifyDataSourceStartedRequest& request,
68433     DeferredNotifyDataSourceStartedResponse response) {
68434   RemoteProducer* producer = GetProducerForCurrentRequest();
68435   if (!producer) {
68436     PERFETTO_DLOG(
68437         "Producer invoked NotifyDataSourceStarted() before "
68438         "InitializeConnection()");
68439     if (response.IsBound())
68440       response.Reject();
68441     return;
68442   }
68443   producer->service_endpoint->NotifyDataSourceStarted(request.data_source_id());
68444 
68445   // NotifyDataSourceStopped shouldn't expect any meaningful response, avoid
68446   // a useless IPC in that case.
68447   if (response.IsBound()) {
68448     response.Resolve(ipc::AsyncResult<
68449                      protos::gen::NotifyDataSourceStartedResponse>::Create());
68450   }
68451 }
68452 
NotifyDataSourceStopped(const protos::gen::NotifyDataSourceStoppedRequest & request,DeferredNotifyDataSourceStoppedResponse response)68453 void ProducerIPCService::NotifyDataSourceStopped(
68454     const protos::gen::NotifyDataSourceStoppedRequest& request,
68455     DeferredNotifyDataSourceStoppedResponse response) {
68456   RemoteProducer* producer = GetProducerForCurrentRequest();
68457   if (!producer) {
68458     PERFETTO_DLOG(
68459         "Producer invoked NotifyDataSourceStopped() before "
68460         "InitializeConnection()");
68461     if (response.IsBound())
68462       response.Reject();
68463     return;
68464   }
68465   producer->service_endpoint->NotifyDataSourceStopped(request.data_source_id());
68466 
68467   // NotifyDataSourceStopped shouldn't expect any meaningful response, avoid
68468   // a useless IPC in that case.
68469   if (response.IsBound()) {
68470     response.Resolve(ipc::AsyncResult<
68471                      protos::gen::NotifyDataSourceStoppedResponse>::Create());
68472   }
68473 }
68474 
ActivateTriggers(const protos::gen::ActivateTriggersRequest & proto_req,DeferredActivateTriggersResponse resp)68475 void ProducerIPCService::ActivateTriggers(
68476     const protos::gen::ActivateTriggersRequest& proto_req,
68477     DeferredActivateTriggersResponse resp) {
68478   RemoteProducer* producer = GetProducerForCurrentRequest();
68479   if (!producer) {
68480     PERFETTO_DLOG(
68481         "Producer invoked ActivateTriggers() before InitializeConnection()");
68482     if (resp.IsBound())
68483       resp.Reject();
68484     return;
68485   }
68486   std::vector<std::string> triggers;
68487   for (const auto& name : proto_req.trigger_names()) {
68488     triggers.push_back(name);
68489   }
68490   producer->service_endpoint->ActivateTriggers(triggers);
68491   // ActivateTriggers shouldn't expect any meaningful response, avoid
68492   // a useless IPC in that case.
68493   if (resp.IsBound()) {
68494     resp.Resolve(
68495         ipc::AsyncResult<protos::gen::ActivateTriggersResponse>::Create());
68496   }
68497 }
68498 
GetAsyncCommand(const protos::gen::GetAsyncCommandRequest &,DeferredGetAsyncCommandResponse response)68499 void ProducerIPCService::GetAsyncCommand(
68500     const protos::gen::GetAsyncCommandRequest&,
68501     DeferredGetAsyncCommandResponse response) {
68502   RemoteProducer* producer = GetProducerForCurrentRequest();
68503   if (!producer) {
68504     PERFETTO_DLOG(
68505         "Producer invoked GetAsyncCommand() before "
68506         "InitializeConnection()");
68507     return response.Reject();
68508   }
68509   // Keep the back channel open, without ever resolving the ipc::Deferred fully,
68510   // to send async commands to the RemoteProducer (e.g., starting/stopping a
68511   // data source).
68512   producer->async_producer_commands = std::move(response);
68513 
68514   // Service may already have issued the OnTracingSetup() event, in which case
68515   // we should forward it to the producer now.
68516   if (producer->send_setup_tracing_on_async_commands_bound)
68517     producer->SendSetupTracing();
68518 }
68519 
Sync(const protos::gen::SyncRequest &,DeferredSyncResponse resp)68520 void ProducerIPCService::Sync(const protos::gen::SyncRequest&,
68521                               DeferredSyncResponse resp) {
68522   RemoteProducer* producer = GetProducerForCurrentRequest();
68523   if (!producer) {
68524     PERFETTO_DLOG("Producer invoked Sync() before InitializeConnection()");
68525     return resp.Reject();
68526   }
68527   auto weak_this = weak_ptr_factory_.GetWeakPtr();
68528   auto resp_it = pending_syncs_.insert(pending_syncs_.end(), std::move(resp));
68529   auto callback = [weak_this, resp_it]() {
68530     if (!weak_this)
68531       return;
68532     auto pending_resp = std::move(*resp_it);
68533     weak_this->pending_syncs_.erase(resp_it);
68534     pending_resp.Resolve(ipc::AsyncResult<protos::gen::SyncResponse>::Create());
68535   };
68536   producer->service_endpoint->Sync(callback);
68537 }
68538 
68539 ////////////////////////////////////////////////////////////////////////////////
68540 // RemoteProducer methods
68541 ////////////////////////////////////////////////////////////////////////////////
68542 
68543 ProducerIPCService::RemoteProducer::RemoteProducer() = default;
68544 ProducerIPCService::RemoteProducer::~RemoteProducer() = default;
68545 
68546 // Invoked by the |core_service_| business logic after the ConnectProducer()
68547 // call. There is nothing to do here, we really expected the ConnectProducer()
68548 // to just work in the local case.
OnConnect()68549 void ProducerIPCService::RemoteProducer::OnConnect() {}
68550 
68551 // Invoked by the |core_service_| business logic after we destroy the
68552 // |service_endpoint| (in the RemoteProducer dtor).
OnDisconnect()68553 void ProducerIPCService::RemoteProducer::OnDisconnect() {}
68554 
68555 // Invoked by the |core_service_| business logic when it wants to create a new
68556 // data source.
SetupDataSource(DataSourceInstanceID dsid,const DataSourceConfig & cfg)68557 void ProducerIPCService::RemoteProducer::SetupDataSource(
68558     DataSourceInstanceID dsid,
68559     const DataSourceConfig& cfg) {
68560   if (!async_producer_commands.IsBound()) {
68561     PERFETTO_DLOG(
68562         "The Service tried to create a new data source but the remote Producer "
68563         "has not yet initialized the connection");
68564     return;
68565   }
68566   auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
68567   cmd.set_has_more(true);
68568   cmd->mutable_setup_data_source()->set_new_instance_id(dsid);
68569   *cmd->mutable_setup_data_source()->mutable_config() = cfg;
68570   async_producer_commands.Resolve(std::move(cmd));
68571 }
68572 
68573 // Invoked by the |core_service_| business logic when it wants to start a new
68574 // data source.
StartDataSource(DataSourceInstanceID dsid,const DataSourceConfig & cfg)68575 void ProducerIPCService::RemoteProducer::StartDataSource(
68576     DataSourceInstanceID dsid,
68577     const DataSourceConfig& cfg) {
68578   if (!async_producer_commands.IsBound()) {
68579     PERFETTO_DLOG(
68580         "The Service tried to start a new data source but the remote Producer "
68581         "has not yet initialized the connection");
68582     return;
68583   }
68584   auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
68585   cmd.set_has_more(true);
68586   cmd->mutable_start_data_source()->set_new_instance_id(dsid);
68587   *cmd->mutable_start_data_source()->mutable_config() = cfg;
68588   async_producer_commands.Resolve(std::move(cmd));
68589 }
68590 
StopDataSource(DataSourceInstanceID dsid)68591 void ProducerIPCService::RemoteProducer::StopDataSource(
68592     DataSourceInstanceID dsid) {
68593   if (!async_producer_commands.IsBound()) {
68594     PERFETTO_DLOG(
68595         "The Service tried to stop a data source but the remote Producer "
68596         "has not yet initialized the connection");
68597     return;
68598   }
68599   auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
68600   cmd.set_has_more(true);
68601   cmd->mutable_stop_data_source()->set_instance_id(dsid);
68602   async_producer_commands.Resolve(std::move(cmd));
68603 }
68604 
OnTracingSetup()68605 void ProducerIPCService::RemoteProducer::OnTracingSetup() {
68606   if (!async_producer_commands.IsBound()) {
68607     // Service may call this before the producer issued GetAsyncCommand.
68608     send_setup_tracing_on_async_commands_bound = true;
68609     return;
68610   }
68611   SendSetupTracing();
68612 }
68613 
SendSetupTracing()68614 void ProducerIPCService::RemoteProducer::SendSetupTracing() {
68615   PERFETTO_CHECK(async_producer_commands.IsBound());
68616   PERFETTO_CHECK(service_endpoint->shared_memory());
68617   auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
68618   cmd.set_has_more(true);
68619   auto setup_tracing = cmd->mutable_setup_tracing();
68620   if (!service_endpoint->IsShmemProvidedByProducer()) {
68621     // Nominal case (% Chrome): service provides SMB.
68622     setup_tracing->set_shared_buffer_page_size_kb(
68623         static_cast<uint32_t>(service_endpoint->shared_buffer_page_size_kb()));
68624     const int shm_fd =
68625         static_cast<PosixSharedMemory*>(service_endpoint->shared_memory())
68626             ->fd();
68627     cmd.set_fd(shm_fd);
68628   }
68629   async_producer_commands.Resolve(std::move(cmd));
68630 }
68631 
Flush(FlushRequestID flush_request_id,const DataSourceInstanceID * data_source_ids,size_t num_data_sources)68632 void ProducerIPCService::RemoteProducer::Flush(
68633     FlushRequestID flush_request_id,
68634     const DataSourceInstanceID* data_source_ids,
68635     size_t num_data_sources) {
68636   if (!async_producer_commands.IsBound()) {
68637     PERFETTO_DLOG(
68638         "The Service tried to request a flush but the remote Producer has not "
68639         "yet initialized the connection");
68640     return;
68641   }
68642   auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
68643   cmd.set_has_more(true);
68644   for (size_t i = 0; i < num_data_sources; i++)
68645     cmd->mutable_flush()->add_data_source_ids(data_source_ids[i]);
68646   cmd->mutable_flush()->set_request_id(flush_request_id);
68647   async_producer_commands.Resolve(std::move(cmd));
68648 }
68649 
ClearIncrementalState(const DataSourceInstanceID * data_source_ids,size_t num_data_sources)68650 void ProducerIPCService::RemoteProducer::ClearIncrementalState(
68651     const DataSourceInstanceID* data_source_ids,
68652     size_t num_data_sources) {
68653   if (!async_producer_commands.IsBound()) {
68654     PERFETTO_DLOG(
68655         "The Service tried to request an incremental state invalidation, but "
68656         "the remote Producer has not yet initialized the connection");
68657     return;
68658   }
68659   auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
68660   cmd.set_has_more(true);
68661   for (size_t i = 0; i < num_data_sources; i++)
68662     cmd->mutable_clear_incremental_state()->add_data_source_ids(
68663         data_source_ids[i]);
68664   async_producer_commands.Resolve(std::move(cmd));
68665 }
68666 
68667 }  // namespace perfetto
68668 // gen_amalgamated begin source: src/tracing/ipc/service/service_ipc_host_impl.cc
68669 // gen_amalgamated begin header: src/tracing/ipc/service/service_ipc_host_impl.h
68670 // gen_amalgamated begin header: include/perfetto/ext/tracing/ipc/service_ipc_host.h
68671 /*
68672  * Copyright (C) 2017 The Android Open Source Project
68673  *
68674  * Licensed under the Apache License, Version 2.0 (the "License");
68675  * you may not use this file except in compliance with the License.
68676  * You may obtain a copy of the License at
68677  *
68678  *      http://www.apache.org/licenses/LICENSE-2.0
68679  *
68680  * Unless required by applicable law or agreed to in writing, software
68681  * distributed under the License is distributed on an "AS IS" BASIS,
68682  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68683  * See the License for the specific language governing permissions and
68684  * limitations under the License.
68685  */
68686 
68687 #ifndef INCLUDE_PERFETTO_EXT_TRACING_IPC_SERVICE_IPC_HOST_H_
68688 #define INCLUDE_PERFETTO_EXT_TRACING_IPC_SERVICE_IPC_HOST_H_
68689 
68690 #include <memory>
68691 
68692 // gen_amalgamated expanded: #include "perfetto/base/export.h"
68693 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
68694 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
68695 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
68696 
68697 namespace perfetto {
68698 namespace base {
68699 class TaskRunner;
68700 }  // namespace base.
68701 
68702 class TracingService;
68703 
68704 // Creates an instance of the service (business logic + UNIX socket transport).
68705 // Exposed to:
68706 //   The code in the tracing client that will host the service e.g., traced.
68707 // Implemented in:
68708 //   src/tracing/ipc/service/service_ipc_host_impl.cc
68709 class PERFETTO_EXPORT ServiceIPCHost {
68710  public:
68711   static std::unique_ptr<ServiceIPCHost> CreateInstance(base::TaskRunner*);
68712   virtual ~ServiceIPCHost();
68713 
68714   // Start listening on the Producer & Consumer ports. Returns false in case of
68715   // failure (e.g., something else is listening on |socket_name|).
68716   virtual bool Start(const char* producer_socket_name,
68717                      const char* consumer_socket_name) = 0;
68718 
68719   // Like the above, but takes two file descriptors to already bound sockets.
68720   // This is used when building as part of the Android tree, where init opens
68721   // and binds the socket beore exec()-ing us.
68722   virtual bool Start(base::ScopedSocketHandle producer_socket_fd,
68723                      base::ScopedSocketHandle consumer_socket_fd) = 0;
68724 
68725   virtual TracingService* service() const = 0;
68726 
68727  protected:
68728   ServiceIPCHost();
68729 
68730  private:
68731   ServiceIPCHost(const ServiceIPCHost&) = delete;
68732   ServiceIPCHost& operator=(const ServiceIPCHost&) = delete;
68733 };
68734 
68735 }  // namespace perfetto
68736 
68737 #endif  // INCLUDE_PERFETTO_EXT_TRACING_IPC_SERVICE_IPC_HOST_H_
68738 /*
68739  * Copyright (C) 2017 The Android Open Source Project
68740  *
68741  * Licensed under the Apache License, Version 2.0 (the "License");
68742  * you may not use this file except in compliance with the License.
68743  * You may obtain a copy of the License at
68744  *
68745  *      http://www.apache.org/licenses/LICENSE-2.0
68746  *
68747  * Unless required by applicable law or agreed to in writing, software
68748  * distributed under the License is distributed on an "AS IS" BASIS,
68749  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68750  * See the License for the specific language governing permissions and
68751  * limitations under the License.
68752  */
68753 
68754 #ifndef SRC_TRACING_IPC_SERVICE_SERVICE_IPC_HOST_IMPL_H_
68755 #define SRC_TRACING_IPC_SERVICE_SERVICE_IPC_HOST_IMPL_H_
68756 
68757 #include <memory>
68758 
68759 // gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/service_ipc_host.h"
68760 
68761 namespace perfetto {
68762 
68763 namespace ipc {
68764 class Host;
68765 }
68766 
68767 // The implementation of the IPC host for the tracing service. This class does
68768 // very few things: it mostly initializes the IPC transport. The actual
68769 // implementation of the IPC <> Service business logic glue lives in
68770 // producer_ipc_service.cc and consumer_ipc_service.cc.
68771 class ServiceIPCHostImpl : public ServiceIPCHost {
68772  public:
68773   ServiceIPCHostImpl(base::TaskRunner*);
68774   ~ServiceIPCHostImpl() override;
68775 
68776   // ServiceIPCHost implementation.
68777   bool Start(const char* producer_socket_name,
68778              const char* consumer_socket_name) override;
68779   bool Start(base::ScopedSocketHandle producer_socket_fd,
68780              base::ScopedSocketHandle consumer_socket_fd) override;
68781 
68782   TracingService* service() const override;
68783 
68784  private:
68785   bool DoStart();
68786   void Shutdown();
68787 
68788   base::TaskRunner* const task_runner_;
68789   std::unique_ptr<TracingService> svc_;  // The service business logic.
68790 
68791   // The IPC host that listens on the Producer socket. It owns the
68792   // PosixServiceProducerPort instance which deals with all producers' IPC(s).
68793   std::unique_ptr<ipc::Host> producer_ipc_port_;
68794 
68795   // As above, but for the Consumer port.
68796   std::unique_ptr<ipc::Host> consumer_ipc_port_;
68797 };
68798 
68799 }  // namespace perfetto
68800 
68801 #endif  // SRC_TRACING_IPC_SERVICE_SERVICE_IPC_HOST_IMPL_H_
68802 /*
68803  * Copyright (C) 2017 The Android Open Source Project
68804  *
68805  * Licensed under the Apache License, Version 2.0 (the "License");
68806  * you may not use this file except in compliance with the License.
68807  * You may obtain a copy of the License at
68808  *
68809  *      http://www.apache.org/licenses/LICENSE-2.0
68810  *
68811  * Unless required by applicable law or agreed to in writing, software
68812  * distributed under the License is distributed on an "AS IS" BASIS,
68813  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68814  * See the License for the specific language governing permissions and
68815  * limitations under the License.
68816  */
68817 
68818 // gen_amalgamated expanded: #include "src/tracing/ipc/service/service_ipc_host_impl.h"
68819 
68820 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
68821 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
68822 // gen_amalgamated expanded: #include "perfetto/ext/ipc/host.h"
68823 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
68824 // gen_amalgamated expanded: #include "src/tracing/ipc/posix_shared_memory.h"
68825 // gen_amalgamated expanded: #include "src/tracing/ipc/service/consumer_ipc_service.h"
68826 // gen_amalgamated expanded: #include "src/tracing/ipc/service/producer_ipc_service.h"
68827 
68828 namespace perfetto {
68829 
68830 // TODO(fmayer): implement per-uid connection limit (b/69093705).
68831 
68832 // Implements the publicly exposed factory method declared in
68833 // include/tracing/posix_ipc/posix_service_host.h.
CreateInstance(base::TaskRunner * task_runner)68834 std::unique_ptr<ServiceIPCHost> ServiceIPCHost::CreateInstance(
68835     base::TaskRunner* task_runner) {
68836   return std::unique_ptr<ServiceIPCHost>(new ServiceIPCHostImpl(task_runner));
68837 }
68838 
ServiceIPCHostImpl(base::TaskRunner * task_runner)68839 ServiceIPCHostImpl::ServiceIPCHostImpl(base::TaskRunner* task_runner)
68840     : task_runner_(task_runner) {}
68841 
~ServiceIPCHostImpl()68842 ServiceIPCHostImpl::~ServiceIPCHostImpl() {}
68843 
Start(const char * producer_socket_name,const char * consumer_socket_name)68844 bool ServiceIPCHostImpl::Start(const char* producer_socket_name,
68845                                const char* consumer_socket_name) {
68846   PERFETTO_CHECK(!svc_);  // Check if already started.
68847 
68848   // Initialize the IPC transport.
68849   producer_ipc_port_ =
68850       ipc::Host::CreateInstance(producer_socket_name, task_runner_);
68851   consumer_ipc_port_ =
68852       ipc::Host::CreateInstance(consumer_socket_name, task_runner_);
68853   return DoStart();
68854 }
68855 
Start(base::ScopedSocketHandle producer_socket_fd,base::ScopedSocketHandle consumer_socket_fd)68856 bool ServiceIPCHostImpl::Start(base::ScopedSocketHandle producer_socket_fd,
68857                                base::ScopedSocketHandle consumer_socket_fd) {
68858   PERFETTO_CHECK(!svc_);  // Check if already started.
68859 
68860   // Initialize the IPC transport.
68861   producer_ipc_port_ =
68862       ipc::Host::CreateInstance(std::move(producer_socket_fd), task_runner_);
68863   consumer_ipc_port_ =
68864       ipc::Host::CreateInstance(std::move(consumer_socket_fd), task_runner_);
68865   return DoStart();
68866 }
68867 
DoStart()68868 bool ServiceIPCHostImpl::DoStart() {
68869   // Create and initialize the platform-independent tracing business logic.
68870   std::unique_ptr<SharedMemory::Factory> shm_factory(
68871       new PosixSharedMemory::Factory());
68872   svc_ = TracingService::CreateInstance(std::move(shm_factory), task_runner_);
68873 
68874   if (!producer_ipc_port_ || !consumer_ipc_port_) {
68875     Shutdown();
68876     return false;
68877   }
68878 
68879   // TODO(fmayer): add a test that destroyes the ServiceIPCHostImpl soon after
68880   // Start() and checks that no spurious callbacks are issued.
68881   bool producer_service_exposed = producer_ipc_port_->ExposeService(
68882       std::unique_ptr<ipc::Service>(new ProducerIPCService(svc_.get())));
68883   PERFETTO_CHECK(producer_service_exposed);
68884 
68885   bool consumer_service_exposed = consumer_ipc_port_->ExposeService(
68886       std::unique_ptr<ipc::Service>(new ConsumerIPCService(svc_.get())));
68887   PERFETTO_CHECK(consumer_service_exposed);
68888 
68889   return true;
68890 }
68891 
service() const68892 TracingService* ServiceIPCHostImpl::service() const {
68893   return svc_.get();
68894 }
68895 
Shutdown()68896 void ServiceIPCHostImpl::Shutdown() {
68897   // TODO(primiano): add a test that causes the Shutdown() and checks that no
68898   // spurious callbacks are issued.
68899   producer_ipc_port_.reset();
68900   consumer_ipc_port_.reset();
68901   svc_.reset();
68902 }
68903 
68904 // Definitions for the base class ctor/dtor.
68905 ServiceIPCHost::ServiceIPCHost() = default;
68906 ServiceIPCHost::~ServiceIPCHost() = default;
68907 
68908 }  // namespace perfetto
68909 // gen_amalgamated begin source: src/tracing/internal/system_tracing_backend.cc
68910 /*
68911  * Copyright (C) 2019 The Android Open Source Project
68912  *
68913  * Licensed under the Apache License, Version 2.0 (the "License");
68914  * you may not use this file except in compliance with the License.
68915  * You may obtain a copy of the License at
68916  *
68917  *      http://www.apache.org/licenses/LICENSE-2.0
68918  *
68919  * Unless required by applicable law or agreed to in writing, software
68920  * distributed under the License is distributed on an "AS IS" BASIS,
68921  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68922  * See the License for the specific language governing permissions and
68923  * limitations under the License.
68924  */
68925 
68926 // gen_amalgamated expanded: #include "perfetto/tracing/internal/system_tracing_backend.h"
68927 
68928 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
68929 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
68930 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
68931 // gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/consumer_ipc_client.h"
68932 // gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/default_socket.h"
68933 // gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/producer_ipc_client.h"
68934 
68935 namespace perfetto {
68936 namespace internal {
68937 
68938 // static
GetInstance()68939 TracingBackend* SystemTracingBackend::GetInstance() {
68940   static auto* instance = new SystemTracingBackend();
68941   return instance;
68942 }
68943 
SystemTracingBackend()68944 SystemTracingBackend::SystemTracingBackend() {}
68945 
ConnectProducer(const ConnectProducerArgs & args)68946 std::unique_ptr<ProducerEndpoint> SystemTracingBackend::ConnectProducer(
68947     const ConnectProducerArgs& args) {
68948   PERFETTO_DCHECK(args.task_runner->RunsTasksOnCurrentThread());
68949 
68950   auto endpoint = ProducerIPCClient::Connect(
68951       GetProducerSocket(), args.producer, args.producer_name, args.task_runner,
68952       TracingService::ProducerSMBScrapingMode::kEnabled,
68953       args.shmem_size_hint_bytes, args.shmem_page_size_hint_bytes, nullptr,
68954       nullptr, ProducerIPCClient::ConnectionFlags::kRetryIfUnreachable);
68955   PERFETTO_CHECK(endpoint);
68956   return endpoint;
68957 }
68958 
ConnectConsumer(const ConnectConsumerArgs & args)68959 std::unique_ptr<ConsumerEndpoint> SystemTracingBackend::ConnectConsumer(
68960     const ConnectConsumerArgs& args) {
68961   auto endpoint = ConsumerIPCClient::Connect(GetConsumerSocket(), args.consumer,
68962                                              args.task_runner);
68963   PERFETTO_CHECK(endpoint);
68964   return endpoint;
68965 }
68966 
68967 }  // namespace internal
68968 }  // namespace perfetto
68969 // gen_amalgamated begin source: src/tracing/platform_posix.cc
68970 /*
68971  * Copyright (C) 2019 The Android Open Source Project
68972  *
68973  * Licensed under the Apache License, Version 2.0 (the "License");
68974  * you may not use this file except in compliance with the License.
68975  * You may obtain a copy of the License at
68976  *
68977  *      http://www.apache.org/licenses/LICENSE-2.0
68978  *
68979  * Unless required by applicable law or agreed to in writing, software
68980  * distributed under the License is distributed on an "AS IS" BASIS,
68981  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68982  * See the License for the specific language governing permissions and
68983  * limitations under the License.
68984  */
68985 
68986 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
68987 
68988 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
68989     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
68990     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
68991 
68992 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
68993 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_task_runner.h"
68994 // gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_tls.h"
68995 // gen_amalgamated expanded: #include "perfetto/tracing/platform.h"
68996 // gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
68997 
68998 #include <pthread.h>
68999 #include <stdlib.h>
69000 
69001 namespace perfetto {
69002 
69003 namespace {
69004 
69005 class PlatformPosix : public Platform {
69006  public:
69007   PlatformPosix();
69008   ~PlatformPosix() override;
69009 
69010   ThreadLocalObject* GetOrCreateThreadLocalObject() override;
69011   std::unique_ptr<base::TaskRunner> CreateTaskRunner(
69012       const CreateTaskRunnerArgs&) override;
69013   std::string GetCurrentProcessName() override;
69014 
69015  private:
69016   pthread_key_t tls_key_{};
69017 };
69018 
69019 using ThreadLocalObject = Platform::ThreadLocalObject;
69020 
PlatformPosix()69021 PlatformPosix::PlatformPosix() {
69022   auto tls_dtor = [](void* obj) {
69023     delete static_cast<ThreadLocalObject*>(obj);
69024   };
69025   PERFETTO_CHECK(pthread_key_create(&tls_key_, tls_dtor) == 0);
69026 }
69027 
~PlatformPosix()69028 PlatformPosix::~PlatformPosix() {
69029   pthread_key_delete(tls_key_);
69030 }
69031 
GetOrCreateThreadLocalObject()69032 ThreadLocalObject* PlatformPosix::GetOrCreateThreadLocalObject() {
69033   // In chromium this should be implemented using base::ThreadLocalStorage.
69034   auto tls = static_cast<ThreadLocalObject*>(pthread_getspecific(tls_key_));
69035   if (!tls) {
69036     tls = ThreadLocalObject::CreateInstance().release();
69037     pthread_setspecific(tls_key_, tls);
69038   }
69039   return tls;
69040 }
69041 
CreateTaskRunner(const CreateTaskRunnerArgs &)69042 std::unique_ptr<base::TaskRunner> PlatformPosix::CreateTaskRunner(
69043     const CreateTaskRunnerArgs&) {
69044   return std::unique_ptr<base::TaskRunner>(
69045       new base::ThreadTaskRunner(base::ThreadTaskRunner::CreateAndStart()));
69046 }
69047 
GetCurrentProcessName()69048 std::string PlatformPosix::GetCurrentProcessName() {
69049 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
69050     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
69051   std::string cmdline;
69052   base::ReadFile("/proc/self/cmdline", &cmdline);
69053   return cmdline.substr(0, cmdline.find('\0'));
69054 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
69055   return std::string(getprogname());
69056 #else
69057   return "unknown_producer";
69058 #endif
69059 }
69060 
69061 }  // namespace
69062 
69063 // static
GetDefaultPlatform()69064 Platform* Platform::GetDefaultPlatform() {
69065   static PlatformPosix* instance = new PlatformPosix();
69066   return instance;
69067 }
69068 
69069 }  // namespace perfetto
69070 #endif  // OS_LINUX || OS_ANDROID || OS_APPLE
69071 
69072